展开R data.frame list列,保留行中的其他值

时间:2015-07-22 00:23:18

标签: r list dataframe

我需要高效率#34;展开" R data.frame中的列表列。例如,如果我将data.frame定义为:

dbt <- data.frame(values=c(1,1,1,1,2,3,4), 
                  parm1=c("A","B","C","A","B","C","B"),
                  parm2=c("d","d","a","b","c","a","a"))

然后,假设分析生成一列作为列表,类似于以下输出:

agg <- aggregate(values ~ parm1 + parm2, data=dbt, 
                 FUN=function(x) {return(list(x))})

聚合的data.frame看起来像(其中class(agg $ values)==&#34; list&#34;):

  parm1 parm2 values
1     B     a      4
2     C     a   1, 3
3     A     b      1
4     B     c      2
5     A     d      1
6     B     d      1

我想展开&#34;价值观&#34;专栏,重复parm1&amp;在所有data.frame行中,以有效的方式为列表的每个元素添加2个值(添加更多行)。

在顶级我写了一个函数,它在一个在apply中调用的for循环中展开。它的确实效率低下(聚合的data.frame需要大约一个小时才能创建,将近24小时才能展开,完全展开的数据有大约500,000条记录)。我使用的顶级是:

unrolled.data <- do.call(rbind, apply(agg, 1, FUN=unroll.data))

该函数只调用value列对象上的unlist(),然后在for循环中构建一个data.frame对象作为返回的对象。

环境有些限制,tidyr,data.table和splitstackshape库对我来说是不可用的,它不仅需要在base ::中找到的函数,还要限于v3.1.1及之前的函数。因此,this (not really a duplicate) question中的答案不适用。

有关更快的建议吗?

谢谢!

1 个答案:

答案 0 :(得分:3)

使用基数R,您可以尝试

_Bool

替代选择(感谢@thelatemail)

with(agg, {
    data.frame(
        lapply(agg[,1:2], rep, times=lengths(values)),
        values=unlist(values)
    )
})
#      parm1 parm2 values
# 1.2      B     a      4
# 1.31     C     a      1
# 1.32     C     a      3
# 2.1      A     b      1
# 3.2      B     c      2
# 4.1      A     d      1
# 4.2      B     d      1