Domanda

Let's say I have some models stored in a list:

mods <- list()
mods[[1]] <- lm(mpg ~ disp, data = mtcars)
mods[[2]] <- lm(mpg ~ disp + factor(cyl), data = mtcars)
mods[[3]] <- lm(mpg ~ disp * factor(cyl), data = mtcars)

And I want to compare them using stats::AIC. I'm looking for the output I would get from AIC(mods[[1]], mods[[2]], mods[[3]]), but I'd like it to generalize to an arbitrarily long list. I thought that

do.call(AIC, mods)

would work, but it returns something that's very verbose and unhelpful. (If the list is named, an error results unless one of the names is object, corresponding the the first argument of AIC, but then you just get the verbose output again.)

After the failure of do.call, I started thinking about an eval(parse()) solution, but I figured I should ask here first.

È stato utile?

Soluzione

summary(do.call(AIC, mods))
       df         AIC       
 Min.   :3   Min.   :153.4  
 1st Qu.:4   1st Qu.:159.6  
 Median :5   Median :165.8  
 Mean   :5   Mean   :163.1  
 3rd Qu.:6   3rd Qu.:168.0  
 Max.   :7   Max.   :170.2  

But this likely isn't what you want. Baptiste has the answer:

my.aic <- function(x) {
  x <- do.call(AIC, x)
  rownames(x) <- NULL
  return(x)
}
my.aic(mods)
##   df      AIC
## 1  3 170.2094
## 2  5 165.7680
## 3  7 153.4352

This is rather close to:

AIC(mods[[1]], mods[[2]], mods[[3]])
##           df      AIC
## mods[[1]]  3 170.2094
## mods[[2]]  5 165.7680
## mods[[3]]  7 153.4352

Altri suggerimenti

Here's a solution using eval(parse()). Luckily Matthew gave a better answer before I even had this typed up.

AIC_l <- function(L, FUN = "AIC") {
    args <- paste0("mods[[", seq_along(L), "]]", collapse = ", ")
    my_call <- paste0(FUN, "(", args, ")")
    eval(parse(text = my_call))
}
AIC_l(L = 1:3, FUN = "AIC")
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top