【问题标题】:Create nested data.tables by collapsing rows into new data.tables通过将行折叠到新的 data.tables 中来创建嵌套的 data.tables
【发布时间】:2014-08-21 16:08:20
【问题描述】:

如何创建包含嵌套 data.tables 的 data.table?

示例

set.seed(7908)
dt <- data.table(x=1:5)[,list(y=letters[1:x],z=sample(1:100,x)),by=x]

dt
##     x y  z
##  1: 1 a 13
##  2: 2 a 27
##  3: 2 b 87
##  4: 3 a 85
##  5: 3 b 98
##  6: 3 c  1
##  7: 4 a 53
##  8: 4 b 81
##  9: 4 c 64
## 10: 4 d 45
## 11: 5 a 28
## 12: 5 b 26
## 13: 5 c 52
## 14: 5 d 55
## 15: 5 e 12

期望的输出

对于 dt 中 x 的每个唯一值,折叠行并创建一个 data.table,其中 y 和 z 列包含在 dt 的单个列中。结果应如下所示:

##    x        dt.yz
## 1: 1 <data.table>
## 2: 2 <data.table>
## 3: 3 <data.table>
## 4: 4 <data.table>
## 5: 5 <data.table>

在我的实际示例中,我有几个具有不同列的数据表,我想将它们存储在一个元数据表中。

【问题讨论】:

    标签: r nested data.table


    【解决方案1】:

    使用 y 和 z 作为列创建 data.table,然后将其包装在一个列表中,以便它可以“填充”在一行中。将其包装在另一个列表中,您可以在其中分配结果列名称。使用 by=x 对 x 的每个唯一值执行此操作。

    dt2 <- dt[, list(dt.yz=list(data.table(y, z))), by=x]
    dt2
    ##    x        dt.yz
    ## 1: 1 <data.table>
    ## 2: 2 <data.table>
    ## 3: 3 <data.table>
    ## 4: 4 <data.table>
    ## 5: 5 <data.table>
    

    正如 Arun 指出的,使用 .SD 更短、更快,并且可能更方便:

    dt2 <- dt[, list(dt.yz=list(.SD)), by=x]
    ## dt.yz will include all columns not in the `by=`;
    ## Use `.SDcols=` to select specific columns
    

    后面要获取一个data.table的值,根据x的期望值对元data.table(dt2)进行子集化,然后获取列表中的第一个元素(也就是嵌套的data.table) dt.yz 列。

    dt2[x==5,dt.yz[[1]]]
    ##    y  z
    ## 1: a 28
    ## 2: b 26
    ## 3: c 52
    ## 4: d 55
    ## 5: e 12
    

    【讨论】:

    • 您可以改用.SDdt[, list(dt.yz=list(.SD)), by=x]
    • 嗨@Arun。是的,这可能更方便,特别是如果您有很多列。它也可能会稍微快一点,对吧?
    • 对,它会更快(而且更短)。 data.table(.) 较慢,as.data.table(.) 稍快,但先复制。另一方面,.SD 已准备就绪。
    • 逆向过程的机会吗?
    • @Arun 这太棒了!这个模式是tidyverse中的nestunnestdata.table版本(应该多推广;找了很久)...@jangorecki反向操作是:dt[ , dt.yz[[1]], by = x]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 2019-05-13
    • 2019-12-24
    • 2022-10-13
    • 1970-01-01
    • 2019-02-13
    相关资源
    最近更新 更多