【问题标题】:Expand list column of data.tables展开 data.tables 的列表列
【发布时间】:2017-04-01 04:31:02
【问题描述】:

我有一个带有列表列的data.table,其中每个元素都是一个data.table

dt <- data.table(id = c(1, 1, 2),
                 var = list(data.table(a = c(1, 2), b = c(3, 4)),
                            data.table(a = c(5, 6), b = c(7, 8)),
                            data.table(a = 9, b = 10)))

dt
# id             var
# 1:  1 <data.table>
# 2:  1 <data.table>
# 3:  2 <data.table>

现在我想“取消列出”这个结构:

   a  b id
1: 1  3  1
2: 2  4  1
3: 5  7  1
4: 6  8  1
5: 9 10  2

我知道如何使用rbindlist 扩展嵌入的data.table 部分,但只是不知道如何将扁平化的data.table 与变量“id”绑定。

原始数据集包含 3000 万行和数十个变量,因此如果您提出不仅可行而且内存高效的解决方案,我将不胜感激。

【问题讨论】:

  • @Frank 感谢您的评论,但我不得不说此解决方案仅适用于 id 唯一的情况。如果 id 重复,则 var[[1]] 仅检索每个 id 的第一行。我已经修改了我的示例以结合这种情况。
  • 好的,我猜我的答案(如下)已经解决了这个问题。

标签: r data.table


【解决方案1】:

在这种情况下dt[, var[[1]], by=id] 有效。但是,我使用rbindlist 作为OP 提到的:

dt[, r := as.character(.I) ]
res <- dt[, rbindlist(setNames(var, r), id="r")]

如果你真的需要那里的任何变量,然后合并rdt 的行):

res[dt, on=.(r), `:=`(id = i.id)]

这在某些方面比dt[, var[[1]], by=id] 更好:

  • rbindlist 应该比有很多 by= 组的东西更快。
  • 如果dt 中有更多变量,则所有变量都必须以by= 结尾。
  • 可能根本不需要从 dt 继承 vars,因为以后总是可以从该表中获取它们,并且它们在那里占用的内存要少得多。

【讨论】:

  • Fwiw,这是我对dt 中“更多变量”的想法的说明:franknarf1.github.io/r-tutorial/_book/…fnyear 列)
  • 谢谢!我正在研究它。
  • 你的代码救了我的命!它超级快。现在我只有一个问题,我认为没有必要在 rbindlist 中添加“setNames”函数,因为没有它我会得到相同的结果。你能解释一下吗?
  • @R.Zhu 酷!是的,很好的观察,你是对的。我想我习惯性地使用它,因为一般来说,人们可能希望链接列不是行号。例如,如果dt[, r := sprintf("%07f.", .I)](行号前导零)或处理文件(如链接示例)并使用文件名进行链接。
  • @Frank 优秀的 R/data.table 教程!感谢分享。
猜你喜欢
  • 2012-08-28
  • 2015-09-07
  • 2019-02-13
  • 2019-12-24
  • 1970-01-01
  • 2020-10-28
  • 2019-11-24
  • 2018-07-07
  • 1970-01-01
相关资源
最近更新 更多