我常常遇到需要为不同变量创建大量类似模型的情况。通常我将它们转储到列表中。以下是虚拟代码的示例:
modlist <- lapply(1:10,function(l) {
data <- data.frame(Y=rnorm(10),X=rnorm(10))
lm(Y~.,data=data)
})
现在以适合为例非常简单:
lapply(modlist,predict)
我有时想做的是从列表中提取一个元素。显而易见的方法是
sapply(modlist,function(l)l$rank)
这就是我想要的,但我想知道是否有更短的方法来获得相同的结果?
答案 0 :(得分:26)
可能这些有点简单:
> z <- list(list(a=1, b=2), list(a=3, b=4))
> sapply(z, `[[`, "b")
[1] 2 4
> sapply(z, get, x="b")
[1] 2 4
你可以定义一个函数:
> `%c%` <- function(x, n)sapply(x, `[[`, n)
> z %c% "b"
[1] 2 4
这看起来像是$
的扩展名:
> `%$%` <- function(x, n) sapply(x, `[[`, as.character(as.list(match.call())$n))
> z%$%b
[1] 2 4
答案 1 :(得分:17)
我通常使用kohske way,但这是另一个技巧:
sapply(modlist, with, rank)
当您需要更多元素时更有用,例如:
sapply(modlist, with, c(rank, df.residual))
我记得我从hadley那里偷了它(从我认为的plyr文档中)。
[[
和with
解决方案之间的主要区别在于缺少元素。当元素缺失时,[[
会返回NULL
。 with
抛出错误,除非全局工作空间中存在与搜索元素同名的对象。例如:
dah <- 1
lapply(modlist, with, dah)
当modlist
没有任何dah
元素时,会返回一个列表。
答案 2 :(得分:1)
使用Hadley的新lowliner包,您可以为map()
提供数字索引或元素名称,以便从列表中优雅地提取组件。 map()
相当于lapply()
,还有一些额外的技巧。
library("lowliner")
l <- list(
list(a = 1, b = 2),
list(a = 3, b = 4)
)
map(l, "b")
map(l, 2)
还有一个版本可以将结果简化为矢量
map_v(l, "a")
map_v(l, 1)