访问R中列表列表的相同命名列表元素

问题描述 投票:11回答:3

我常常遇到需要为不同变量创建大量类似模型的情况。通常我将它们转储到列表中。以下是虚拟代码的示例:

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)

这样做我想要的,但我想知道是否有更短的方法来获得相同的结果?

r
3个回答
19
投票

我通常使用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元素时返回一个列表。


27
投票

可能这些有点简单:

> 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
投票

使用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)
© www.soinside.com 2019 - 2024. All rights reserved.