将常量列添加到嵌套 data.table
add constant column to nested data.table
我正在使用 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>
在我的数据中存在 key/identifier 列(例如,上面 data.table
中的列 a
),但嵌套数据没有此类标识符。我需要处理嵌套数据(参见我的 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
我的 objective 是在将嵌套表绑定在一起之前将其修改为如下所示,以便我知道哪些行与哪些记录相关:
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 表达式中调用的自定义函数来实现这一点,并为该行采用嵌套的 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
或其他我不知道的技术的功能让它更多 efficient/concise.
要达到最终效果,最直接的方法就是
dt[,c[[1]],by=a]
这给出了
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
您可以交替进行
rbindlist( setNames(dt[["c"]], dt[["a"]]), idcol = TRUE )
数据
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))))]
我正在使用 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>
在我的数据中存在 key/identifier 列(例如,上面 data.table
中的列 a
),但嵌套数据没有此类标识符。我需要处理嵌套数据(参见我的 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
我的 objective 是在将嵌套表绑定在一起之前将其修改为如下所示,以便我知道哪些行与哪些记录相关:
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 表达式中调用的自定义函数来实现这一点,并为该行采用嵌套的 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
或其他我不知道的技术的功能让它更多 efficient/concise.
要达到最终效果,最直接的方法就是
dt[,c[[1]],by=a]
这给出了
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
您可以交替进行
rbindlist( setNames(dt[["c"]], dt[["a"]]), idcol = TRUE )
数据
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))))]