0

Can the assign function in R be used to assign object names to models (e.g., gls models)? I'm guessing not b/c I keep getting a warning:

 > Warning messages:
 In assign(paste0(deparse(substitute(mod)), "_", i, j), update(mod,  :
  only the first element is used as variable name

As a result the objects are not created

Is there a way to do this?

Here is my fucntion code if it helps:

#Choose best corARMA structure for model of choice:
  corARMA.chooser <- function(mod,min = 0,max = 3 ) {
    #This function creates 1. object for each combo of ARMA {0:3} 2. AIC table comparing all of these models 
    mod <- get('mod')
    aic.arma <- AIC(mod)
    ps <- 0
    qs <- 0
    for(i in min:max) {
      js <- if(i == 0) c(1:max) else c(min:max)
      for(j in js) {
        arma <-  corARMA(p = i, q = j)
        assign(paste0(deparse(substitute(mod)),'_',i,j), update(mod, .~., correlation = arma), envir = .GlobalEnv)
        aic.arma <- c(aic.arma, AIC(get(paste0(deparse(substitute(mod)),'_',i,j))))
        ps <- c(ps, i)
        qs <- c(qs, i)
      }
      aic.arma.out <- data.frame(ps, qs, aic.arma)
      aic.arma.out
    }
  }

Update:

I tried using the list approach, but I get the error:

Error in names(mod.list) <- c(names(mod.list), paste0(deparse(substitute(mod)),  : 
'names' attribute [1275] must be the same length as the vector [1]
theforestecologist
  • 4,667
  • 5
  • 54
  • 91
  • 1
    Use a `list`. Also an error is different from a warning. – Gregor Thomas Mar 04 '16 at 06:57
  • Bit vague. could you elaborate a bit please? – theforestecologist Mar 04 '16 at 07:05
  • 1
    Rather than trying to assign names to models, you should put models in a list. Naming a list is easy. Doing things to every element of a list is easy. It's much better over all. [See my answer here for a data frame example](http://stackoverflow.com/a/24376207/903061). – Gregor Thomas Mar 04 '16 at 08:47
  • As to the other part, warnings say *Warning*, and mean your code did execute, but there were potential problems that you should verify. They draw your attention to possible problems, but do not necessarily indicate problems. Errors say *Error* and mean the code did not execute at all, they are definitely a problem. When you say you "guess something didn't work", say there was an error, but show the text of a warning, we're left wondering whether it actually worked as expected and you don't realize it or if it did something else how is the result different from your expectation. – Gregor Thomas Mar 04 '16 at 08:51
  • If you need more elaboration, you should share some sample input - hopefully for a very simple case. Your desired output seems fairly clear, but since you *don't* have an error it wouldn't hurt to explicitly state how the output for your sample input is lacking compared to your desired output. – Gregor Thomas Mar 04 '16 at 08:55
  • I'd be happy to help you debug the list approach, but I really would like a sample input. Use some simulated or built-in data and show code to create a model to run this on. – Gregor Thomas Mar 04 '16 at 18:01

2 Answers2

1

EDIT: what actually tears your variable name apart is this line mod <- get('mod') where you overwrite your named instance of mod why do you actually do this? If change your function to this it behaves as I'd expect it to:

corARMA.chooser <- function(modIn,min = 0,max = 3 ) {   
#This function creates 1. object for each combo of ARMA {0:3} 2. AIC table comparing all of these models    mod <- get('modIn')   aic.arma <- AIC(modIn)   ps <- 0   qs <- 0   for(i in min:max) {
js <- if(i == 0) c(1:max) else c(min:max)
 for(j in js) {
  arma <-  corARMA(p = i, q = j)
  browser()
  assign(paste0(deparse(substitute(modIn)),'_',i,j), update(mod, .~., correlation = arma), envir = .GlobalEnv)
  aic.arma <- c(aic.arma, AIC(get(paste0(deparse(substitute(mod)),'_',i,j))))
  ps <- c(ps, i)
  qs <- c(qs, i)
  }
 aic.arma.out <- data.frame(ps, qs, aic.arma)
 aic.arma.out   
 } 
}

hope this is what you were trying to achieve.

David Go
  • 810
  • 1
  • 7
  • 13
  • Can you show your output with the multiple elements? I have run this over and over outside of my function and it works just fine. When I run the line in the function it gives me the warning. – theforestecologist Mar 04 '16 at 16:08
  • I call your function like this: `corARMA.chooser(arima(lh))` as my ts does not match the `update(mod, .~., correlation = arma)` functionality I call update like this: `update(mod)`. The output of `paste0(deparse(substitute(mod)),'_',i,j)` is a vector containing large characters. As you use this output as a variable name in the function assign, It only uses the first element of that vector in my case **"structure(list(coef = structure(2.40000000000009, .Names = \"intercept\"), _01"** if you use instead of your call `paste0(deparse(substitute(mod)),'_',i,j)[1]` the funciton still works identical – David Go Mar 04 '16 at 18:21
  • it might help if you try to reproduce my function call and debug at the assign(...) call. As I said, the first argument is only a variable name, while `paste0(deparse(substitute(mod))` returns a vector which is why (at least in my case) the warning gets thrown – David Go Mar 04 '16 at 18:32
  • I think I finally found your issue – David Go Mar 04 '16 at 21:27
0

Still not sure why the code works alone but not in the function, but it is clear that the deparse(substitute(mod)) is for some reason pulls mod apart to all of its parts first in the function, vs. simply creating a name of the object itself.

Here is my new code that works:

  corARMA.chooser <- function(mod,p = 1,q = 0 ) {
    #This function creates 1. object for each combo of ARMA {0:3} 2. AIC table comparing all of these models 
    mod.list <- NULL
    nms <- NULL
    aic.arma <- AIC(mod)
    ps <- 0
    qs <- 0
    for(i in c(p)) {
      js <- if(i == 0) c(q[q>0]) else c(q)
      for(j in c(js)) {
        arma <-  corARMA(p = i, q = j)
        mod.list <- c(mod.list, list(update(mod, .~., correlation = arma)))
        names(mod.list) <- c(names(mod.list), paste0(deparse(substitute(mod)),'_',i,j))
        aic.arma <- c(aic.arma, AIC(eval(parse(text=(paste0('mod.list$',deparse(substitute(mod)),'_',i,j))))))
        ps <- c(ps, i)
        qs <- c(qs, j)
      }
    } 
      assign(paste0(deparse(substitute(mod)),'_','ARMA'),mod.list, envir = .GlobalEnv)      
      aic.arma.out <- data.frame(p = ps, q = qs, AIC = aic.arma)
      aic.arma.out
  }
theforestecologist
  • 4,667
  • 5
  • 54
  • 91