更简洁的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
相关产品推荐
相关产品推荐

