R - data.table 行中的反透视列表

Posted

技术标签:

【中文标题】R - data.table 行中的反透视列表【英文标题】:R - unpivot list in data.table rows 【发布时间】:2016-09-07 02:58:30 【问题描述】:

我有一个包含多列的数据集,其中 1 列带有列表条目:

DT = data.table(
  x = c(1:5),
  y = seq(2, 10, 2),
  z = list(list("a","b","a"), list("a","c"), list("b","c"), list("a","b","c"), list("b","c","b"))
)

基本上,我试图从 z 列中取消列出 a、b、c,并根据 x 和 y 值聚合数据。

期望的输出:

    z x sum(y)
 1: a 1  4
 2: b 1  2
 3: a 2  4
 4: c 2  4
 5: b 3  6
 6: c 3  6
 7: a 4  8
 8: b 4  8
 9: c 4  8
10: b 5 20
11: c 5 10

我目前的方法比较迂回;我在与 z 列中的列表条目长度相同的列表中创建了具有 x 和 y 值的另外 2 列,然后在聚合之前同时取消列出所有 3 列 - 即总和 y 值,按 z 和 x 分组。

代码(在取消列出和聚合之前):

DT[, listlen := sapply(z, function(x) length(x))]
for (a in c(1:nrow(DT)))
  DT[a, x1:= list(list(rep(DT[a, x], DT[a, listlen])))]
  DT[a, y1:= list(list(rep(DT[a, y], DT[a, listlen])))]
DT_out = data.table(x = unlist(DT[,x1]), y = unlist(DT[,y1]), z = unlist(DT[,z]))

   x  y      z listlen    x1       y1
1: 1  2 <list>       3 1,1,1    2,2,2
2: 2  4 <list>       2   2,2      4,4
3: 3  6 <list>       2   3,3      6,6
4: 4  8 <list>       3 4,4,4    8,8,8
5: 5 10 <list>       3 5,5,5 10,10,10

有没有一种通过 data.table 或 reshape 包的方法可以帮助我融化数据集/这样做更简单?因为我正在处理比这更多的行,所以这一步似乎效率很低。

也非常感谢有关聚合步骤的任何其他帮助!

【问题讨论】:

【参考方案1】:

unlist 你的z 列首先,然后通过by= 正常聚合:

DT[, .(z=unlist(z)), by=.(x,y)][, .(sumy=sum(y)), by=.(x,z)]

#    x z sumy
# 1: 1 a    4
# 2: 1 b    2
# 3: 2 a    4
# 4: 2 c    4
# 5: 3 b    6
# 6: 3 c    6
# 7: 4 a    8
# 8: 4 b    8
# 9: 4 c    8
#10: 5 b   20
#11: 5 c   10

【讨论】:

我们也可以通过repDT[rep(1:.N, lengths(z))][ , .(sumy = sum(y)),.(x, z= unlist(DT$z))]避免这两个组

以上是关于R - data.table 行中的反透视列表的主要内容,如果未能解决你的问题,请参考以下文章

R语言data.table导入数据实战:data.table使用dcast.data.table函数实现透视表(pivot table)

PostgreSQL 中的反透视表

Access SQL 中的反透视

SQL Server 中的反透视表

Databricks/Spark SQL 中的反透视表

spark-sql/Scala 中的反透视列名是数字