rbindlist和嵌套的data.table,使用/不使用get的不同行为

时间:2015-07-08 13:42:56

标签: r data.table

我正在使用jsonlite加载一些JSON数据,这导致一些嵌套数据与下面构建的玩具data.table dt类似(在结构上)。我希望能够使用rbindlist将嵌套的data.table绑定在一起。

设置:

> dt <- data.table(a=c("abc", "def", "ghi"), b=runif(3))
> dt[, c:=list(list(data.table(d=runif(4), e=runif(4))))]
> dt
     a         b            c
1: abc 0.2623218 <data.table>
2: def 0.7092507 <data.table>
3: ghi 0.2795103 <data.table>

使用内置于data.table的NSE,我可以:

> rbindlist(dt[, c])
            d          e
 1: 0.8420476 0.26878325
 2: 0.1704087 0.59654706
 3: 0.6023655 0.42590380
 4: 0.9528841 0.06121386
 5: 0.8420476 0.26878325
 6: 0.1704087 0.59654706
 7: 0.6023655 0.42590380
 8: 0.9528841 0.06121386
 9: 0.8420476 0.26878325
10: 0.1704087 0.59654706
11: 0.6023655 0.42590380
12: 0.9528841 0.06121386

这正是我期望/想要的。此外,原始dt仍未修改:

> dt
     a         b            c
1: abc 0.2623218 <data.table>
2: def 0.7092507 <data.table>
3: ghi 0.2795103 <data.table>

但是,在函数中操作data.table时,我通常希望将get与字符串列名一起使用:

> rbindlist(dt[, get("c")])
           V1         V2
 1: 0.8420476 0.26878325
 2: 0.1704087 0.59654706
 3: 0.6023655 0.42590380
 4: 0.9528841 0.06121386
 5: 0.8420476 0.26878325
 6: 0.1704087 0.59654706
 7: 0.6023655 0.42590380
 8: 0.9528841 0.06121386
 9: 0.8420476 0.26878325
10: 0.1704087 0.59654706
11: 0.6023655 0.42590380
12: 0.9528841 0.06121386

现在列名已丢失,取而代之的是默认的&#34; V1&#34;和&#34; V2&#34;值。有没有办法保留这些名字?

在开发版本(v1.9.5)中,问题比简单地丢失名称更糟糕。执行语句后:rbindlist(dt[, get("c")])整个data.table变得腐败:

> dt
Error in FUN(X[[3L]], ...) : 
  Invalid column: it has dimensions. Can't format it. If it's the result of data.table(table()), use as.data.table(table()) instead.

要清楚,丢失的名称问题发生在v1.9.4(从CRAN安装)和v1.9.5(从github安装)中,但是损坏的data.table问题似乎只影响v1.9.5(如今天 - 2015年7月8日)。

如果我能够坚持使用NSE版本的东西,一切都顺利进行。我的问题是坚持使用NSE版本会涉及编写多个相互调用的NSE函数,这些函数似乎很快就会变得混乱。

是否有任何(非基于NSE的)已知解决方案?此外,这是一个已知问题吗?

1 个答案:

答案 0 :(得分:0)

自从问这个问题以来,这个问题必须在最近5年内得到解决。现在我得到了预期的结果。

> library(data.table)
data.table 1.13.3 IN DEVELOPMENT built 2020-11-17 18:11:47 UTC; jan using 4 threads (see ?getDTthreads).  Latest news: r-datatable.com
> dt <- data.table(a=c("abc", "def", "ghi"), b=runif(3))
> dt[, c:=list(list(data.table(d=runif(4), e=runif(4))))]
> dt
     a         b                 c
1: abc 0.2416624 <data.table[4x2]>
2: def 0.0222938 <data.table[4x2]>
3: ghi 0.3510681 <data.table[4x2]>
> rbindlist(dt[, c])
            d          e
 1: 0.5485731 0.32366420
 2: 0.5457945 0.45173251
 3: 0.6796699 0.03783026
 4: 0.4442776 0.03121024
 5: 0.5485731 0.32366420
 6: 0.5457945 0.45173251
 7: 0.6796699 0.03783026
 8: 0.4442776 0.03121024
 9: 0.5485731 0.32366420
10: 0.5457945 0.45173251
11: 0.6796699 0.03783026
12: 0.4442776 0.03121024
> rbindlist(dt[, get("c")])
            d          e
 1: 0.5485731 0.32366420
 2: 0.5457945 0.45173251
 3: 0.6796699 0.03783026
 4: 0.4442776 0.03121024
 5: 0.5485731 0.32366420
 6: 0.5457945 0.45173251
 7: 0.6796699 0.03783026
 8: 0.4442776 0.03121024
 9: 0.5485731 0.32366420
10: 0.5457945 0.45173251
11: 0.6796699 0.03783026
12: 0.4442776 0.03121024
> dt
     a         b                 c
1: abc 0.2416624 <data.table[4x2]>
2: def 0.0222938 <data.table[4x2]>
3: ghi 0.3510681 <data.table[4x2]>