我们有一个矢量列表(不同长度):
foo <- list(1:3,NULL,2:7)
我们需要的是一个包含两列的data.frame:项目和列表编号,如下所示:
data.frame(Item=c(1:3,2:7), List=c(1,1,1,3,3,3,3,3,3))
此处Item
列是foo
中的项目向量,List
列显示每个项目所属的foo
列表。
这可以像下面这样做:
data.frame(Item=unlist(foo),
List=unlist(lapply(seq_along(foo), function(i) rep(i, length(foo[[i]])))))
但我正在寻找更有创意和更有效的解决方案。你有更好的想法吗?
答案 0 :(得分:2)
此答案取决于“foo”中的数据类型,但您可以在stack
添加names
后尝试list
:
names(foo) <- seq_along(foo)
stack(foo)
# values ind
# 1 1 1
# 2 2 1
# 3 3 1
# 4 2 3
# 5 3 3
# 6 4 3
# 7 5 3
# 8 6 3
# 9 7 3
# Warning message:
# In stack.default(foo) : non-vector elements will be ignored
您当前方法的一个稍微紧凑的版本是使用sapply
而不是lapply
:
> foo <- list(1:3,NULL,2:7)
> data.frame(Item = unlist(foo), List = rep(seq_along(foo), sapply(foo, length)))
答案 1 :(得分:1)
使用plyr
您可以获得更具可读性的解决方案:
library(plyr)
ldply(seq_along(foo),
function(x)data.frame(Item=foo[[x]],
List=rep(x,length(foo[[x]]))))
Item List
1 1 1
2 2 1
3 3 1
4 2 3
5 3 3
6 4 3
7 5 3
8 6 3
9 7 3
答案 2 :(得分:1)
我愿意:
data.frame(Item = unlist(foo),
List = rep(seq_along(foo), sapply(foo, length)))
用sapply(foo, length)
或vapply(foo, length, integer(1))
替换unlist(lapply(foo, length))
也会更有效率。而且我认为你不能走得更快。
效率低但有点创意是:
i <- sapply(foo, Negate(is.null))
do.call(rbind, Map(data.frame, Item = foo[i], List = seq_along(foo)[i]))