You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

更简洁的data.table嵌套列unnest实现方法?

用data.table优雅展开嵌套列(无需辅助列或rep+lengths)

我们有一个包含嵌套列val的data.table:

dt <- data.table(
  grp = c(1, 2, 1, 3, 4),
  val = list("a", c("b", "c"), c("d", "e", "f"), "g", c("h", "i"))
)

显示结果:

> dt
   grp   val
1:   1     a
2:   2   b,c
3:   1 d,e,f
4:   3     g
5:   4   h,i

需求是展开val列,同时保留grp列的原始顺序(1,2,1,3,4),仅使用data.table语法实现。目前用tidyr::unnest可以实现:

> dt %>%
+   unnest(val)
# A tibble: 9 × 2
    grp val
  <dbl> <chr>
1     1 a
2     2 b
3     2 c
4     1 d
5     1 e
6     1 f
7     3 g
8     4 h
9     4 i

现有两种尝试

第一种(借助辅助列):

> dt[, id := .I][, lapply(.SD, unlist), id][, id := NULL][]
   grp val
1:   1   a
2:   2   b
3:   2   c
4:   1   d
5:   1   e
6:   1   f
7:   3   g
8:   4   h
9:   4   i

第二种(使用rep+lengths):

> dt[,.(
  grp = rep(grp,lengths(val)), 
  val = unlist(val)
)]
   grp val
1:   1   a
2:   2   b
3:   2   c
4:   1   d
5:   1   e
6:   1   f
7:   3   g
8:   4   h
9:   4   i

更简洁优雅的实现

可以直接利用data.table的分组语法,按原始行索引(.I)分组,在分组内展开val列,同时自动保留对应行的grp值:

dt[, .(grp, val = unlist(val)), by = .I][, .I := NULL][]

执行结果:

grp val
1:   1   a
2:   2   b
3:   2   c
4:   1   d
5:   1   e
6:   1   f
7:   3   g
8:   4   h
9:   4   i

这个写法无需额外添加辅助列,也不用手动处理rep和lengths,语法更简洁,同时完美保留grp的原始顺序。

内容的提问来源于stack exchange,提问作者ThomasIsCoding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:26:16