我常常遇到需要为不同变量创建大量类似模型的情况。通常我将它们转储到列表中。以下是虚拟代码的示例:
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)
这样做我想要的,但我想知道是否有更短的方法来获得相同的结果?
我通常使用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
元素时返回一个列表。
可能这些有点简单:
> 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
使用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)