4

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

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

这里Itemcolumn 是 中项目的向量fooListcolumns 显示foo每个项目所属的列表。

这可以像下面这样完成:

data.frame(Item=unlist(foo), 
           List=unlist(lapply(seq_along(foo), function(i) rep(i, length(foo[[i]])))))

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

4

3 回答 3

3

这个答案有点取决于“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)))
于 2013-09-21T12:13:13.250 回答
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
于 2013-09-21T12:17:53.080 回答
1

我会做:

data.frame(Item = unlist(foo),
           List = rep(seq_along(foo), sapply(foo, length)))

替换sapply(foo, length)vapply(foo, length, integer(1))orunlist(lapply(foo, length))也会更有效率。而且我认为你不能走得更快。

效率较低但有些创意的是:

i <- sapply(foo, Negate(is.null))
do.call(rbind, Map(data.frame, Item = foo[i], List = seq_along(foo)[i]))
于 2013-09-21T12:19:05.030 回答