2011-05-09 67 views
9

我经常遇到需要为不同变量创建大量类似模型的情况。通常我将它们转储到列表中。下面是伪代码的例子:访问R中列表中的列表中的同名列表元素

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

示例代码返回一个错误的一个版本。 – 2011-05-09 11:11:50

+0

@Joris,它是一个虚拟代码,原则上它不应该工作,因为'simulate'没有被定义。但是,大写的'C'出错了。感谢您指出。 – mpiktas 2011-05-09 12:34:20

+3

我明白了。但是,人们会假设你的虚拟代码运行,并且一个最小可重现的例子通常是一个小的努力来解释一个问题。它避免了我们必须让自己在寻找答案。 – 2011-05-09 12:37:06

回答

14

我通常使用kohske way,但这里有另一个窍门:

sapply(modlist, with, rank) 

当你需要更多的元素,例如:

sapply(modlist, with, c(rank, df.residual)) 

我记得我偷了从哈德利(从plyr文档我认为)这是比较有用的。

+2

感谢,这当然感觉像@哈代码,简单而优雅。 – mpiktas 2011-05-09 12:40:35

+0

@mpiktas''[''''和'with'解决方案之间的主要区别在于缺少元素。 '“[[”'元素丢失时返回'NULL'。 '用'抛出一个错误**,除非在全局工作空间中存在一个名称与搜索元素**相同的对象。所以例如'dah <-1;当modlist没有任何'dah'元素时,lapply(modlist,with,dah)'返回一个列表。 – Marek 2011-05-10 21:19:40

+0

感谢您的补充评论。在我的情况下,列表中的元素不应该有任何缺失的元素,所以错误是值得欢迎的。 – mpiktas 2011-05-11 05:59:04

24

可能这些都有点简单:

> 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

谢谢,我认为这应该是可能的。这是一个可惜我不能接受这两个答案,我选择@Marek纯粹是出于美学原因的答案。我赞成你的。 – mpiktas 2011-05-09 12:39:09

1

随着哈德利的新lowliner包,您可以提供map()数字索引或元素名称优雅地从列表中拔出组件。 map()相当于lapply()有一些额外的技巧。

library("lowliner") 

l <- list(
    list(a = 1, b = 2), 
    list(a = 3, b = 4) 
) 

map(l, "b") 
map(l, 2) 

还有,简化了结果的向量使用foreach包时

map_v(l, "a") 
map_v(l, 1)