我正在使用jsonlite加载一些JSON数据,这导致一些嵌套数据(在结构中)与下面构造的玩具data.table dt类似。
设置:
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>
在我的数据中,存在键/标识符列(例如,上面a
中的列data.table
),但嵌套数据没有这样的标识符。我需要使用嵌套数据(请参阅我的related question),但在使用rbindlist
之前,我想将列a
的值作为嵌套数据的常量列。
例如,第一行中c
的值为:
dt[1, c]
[[1]]
d e
1: 0.27951027 0.6350479
2: 0.45996594 0.6148956
3: 0.29377315 0.8432641
4: 0.01850265 0.1346082
我的目标是修改它,使它在将嵌套表绑定到一起之前看起来如下所示,以便我知道哪些行与哪条记录一起使用:
dt[1, c]
[[1]]
d e a
1: 0.27951027 0.6350479 abc
2: 0.45996594 0.6148956 abc
3: 0.29377315 0.8432641 abc
4: 0.01850265 0.1346082 abc
我可以使用在J-expression中调用的自定义函数来实现这一点,并为该行以及常量列(此示例中为data.table
)获取嵌套a
名称和值。有点像:
add_nested_column <- function(dfl, name, value) {
df <- dfl[[1]] # data.frame wrapped in list per row, pull it out
df[, c(name):=value]
return(list(list(df)))
}
像这样使用:
dt[, key:=1:.N]
dt[, c:=add_nested_column(c, "a", a), by=key]
rbindlist(dt[, c])
d e a
1: 0.27951027 0.6350479 abc
2: 0.45996594 0.6148956 abc
3: 0.29377315 0.8432641 abc
4: 0.01850265 0.1346082 abc
5: 0.27951027 0.6350479 def
6: 0.45996594 0.6148956 def
7: 0.29377315 0.8432641 def
8: 0.01850265 0.1346082 def
9: 0.27951027 0.6350479 ghi
10: 0.45996594 0.6148956 ghi
11: 0.29377315 0.8432641 ghi
12: 0.01850265 0.1346082 ghi
这个解决方案对我来说似乎并不是那么糟糕,但我想知道它是否真的是最佳实践,或者是否有data.table
内置的功能或我不知道的其他技术会使它成为现实更有效/简洁。
答案 0 :(得分:3)
To achieve the end result, the most straightforward way is
dt[,c[[1]],by=a]
which gives
a d e
1: abc 0.9082078 0.66079779
2: abc 0.2016819 0.62911404
3: abc 0.8983897 0.06178627
4: abc 0.9446753 0.20597457
5: def 0.9082078 0.66079779
6: def 0.2016819 0.62911404
7: def 0.8983897 0.06178627
8: def 0.9446753 0.20597457
9: ghi 0.9082078 0.66079779
10: ghi 0.2016819 0.62911404
11: ghi 0.8983897 0.06178627
12: ghi 0.9446753 0.20597457
You can alternately do
rbindlist( setNames(dt[["c"]], dt[["a"]]), idcol = TRUE )
Data
set.seed(1)
dt <- data.table(a=c("abc", "def", "ghi"), b=runif(3))
dt[, c:=list(list(data.table(d=runif(4), e=runif(4))))]