问题
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.
回答1:
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
回答2:
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))
}
来源:https://stackoverflow.com/questions/16630776/how-do-i-pass-every-element-of-a-list-to-a-function-as-unnamed-arguments