将向量列表与data.frame组合在一起,列表编号

时间:2013-09-21 11:48:21

标签: r list vector dataframe

我们有一个矢量列表(不同长度):

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]])))))

但我正在寻找更有创意和更有效的解决方案。你有更好的想法吗?

3 个答案:

答案 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]))