1

I am struggling to write a script which allows for a more flexible approach to compare different linear mixed-effect models making use of the lme4 or nlme package. As I do not want to adjust the script for each and every model I add or drop, I am looking for a dynamic approach. Doing so I would only have to adjust one variable which contains character strings of the model formulas.

This works fine unless anova() comes in. anova() does not accept a list of elements containing the appropriate classes:

###### Here is my problem
# comparing models by means of ANOVA
anova(lme.lst)                                  #### --> does not work
anova(lme.lst[[1]], lme.lst[[2]], lme.lst[[3]]) #### would work but kills the dynamic approach
######

I did not figure a neat way to decompose the list and pass multiple arguments to the anova() function. I tried unlist() without any success.

Here is a minimal example (adapted from lme4 manual, p. 8):

require(lme4)
require(AICcmodavg)

# Variable containing of strings in order to describe the fixed effect terms 
# (wihout response/dependen variable)                                            ### should be orderd from
callModel <- c("angle ~ recipe + temp        + (1|recipe:replicate)",  # model1  ### small
               "angle ~ recipe + temperature + (1|recipe:replicate)",  # model2  ### too                
               "angle ~ recipe * temperature + (1|recipe:replicate)")  # model3  ### BIG

# convert string array 'callFeVar' into a list of formulas
callModel <- sapply(callModel, as.formula)

# create an empty list for safing the results of fitted model 
lme.lst <- list()
# do model fitting in a loop and change list names
for (i in 1 : length(callModel)) {
  lmeTmp <- lmer(callModel[[i]], cake, REML= FALSE)
  lme.lst[i] <- list(lmeTmp)
  names(lme.lst)[i] <- deparse(callModel[[i]])
}
# remove temporary variable
rm(lmeTmp)

# summary of models
lapply(lme.lst, summary)

###### Here is my problem
# comparing models by means of ANOVA
anova(lme.lst)                                  #### --> does not work
anova(lme.lst[[1]], lme.lst[[2]], lme.lst[[3]]) #### would work but kills the dynamic approach
######

# comparing models by means of AICc
aictab(lme.lst)                                 #### accepts list
ToJo
  • 1,339
  • 1
  • 15
  • 26

1 Answers1

5

do.call calls a function with arguments supplied in a list.

do.call(anova, lme.lst)
Hong Ooi
  • 56,353
  • 13
  • 134
  • 187
  • Does not work that way with the minimal example. I get: `Error in anova.merMod(``angle ~ recipe + temp + (1 | recipe:replicate)`` = , : argument "object" is missing, with no default` – ToJo Apr 25 '15 at 12:14
  • 1
    I just fiddled around a bit more figuring the following: When using `do.call`, `anova` does not like the list's name arguments. Therefore, wrapping the list in `unname` does the trick: `do.call(anova, unname(lme.lst))`. Now it would be cool to also pass the `model.names` argument setting it to `names(me.lst)`. Any ideas? However, the latter would only be a "nice-to-have" feature. – ToJo Apr 25 '15 at 12:45