如何在data.table中按分组提取前N行数据?
按分组提取data.table前N行的解决方案
当然可以!在处理大型data.table时,只查看每个分组的前若干行确实是高效探索数据的好办法,我来给你介绍两种实用的实现方式:
方法一:利用.I生成索引提取(适合需复用索引的场景)
.I是data.table的特殊符号,它会返回当前分组内每行在原数据表中的索引位置,我们可以用它来精准定位每个分组的前N行:
- 生成每个分组的前N行索引
比如要提取每个Z分组的前2行,执行以下代码:
library(data.table) DT <- data.table(X=rep(letters[1:3], 50), Y=rep(LETTERS[1:3],each=50))[,Z:=paste0(X,"-",Y)] setkey(DT,Z) # 生成每个分组前2行的索引 index_dt <- DT[,.I[1:2], by=Z] index_dt
运行结果会返回每个分组对应的原表索引:
> index_dt Z V1 1: a-A 1 2: a-A 2 3: a-B 18 4: a-B 19 5: a-C 35 6: a-C 36 7: b-A 51 8: b-A 52 9: b-B 68 10: b-B 69 11: b-C 84 12: b-C 85 13: c-A 101 14: c-A 102 15: c-B 117 16: c-B 118 17: c-C 134 18: c-C 135
- 用索引提取目标数据
把上面得到的索引代入原表,就能直接获取每个分组的前N行:
DT[index_dt$V1]
运行结果:
> DT[index_dt$V1] X Y Z 1: a A a-A 2: a A a-A 3: a B a-B 4: a B a-B 5: a C a-C 6: a C a-C 7: b A b-A 8: b A b-A 9: b B b-B 10: b B b-B 11: b C b-C 12: b C b-C 13: c A c-A 14: c A c-A 15: c B c-B 16: c B c-B 17: c C c-C 18: c C c-C
方法二:直接用head(.SD, N)提取(简洁直观,日常首选)
如果你不需要复用索引,这种写法更直接——.SD代表当前分组的所有列,head(.SD, N)就能直接取每个分组的前N行:
比如要提取每个Z分组的前5行,直接执行:
DT[, head(.SD, 5), by=Z]
运行结果完全符合你期望的格式:
Z X Y 1: a-A a A 2: a-A a A 3: a-A a A 4: a-A a A 5: a-A a A 6: b-B a B 7: b-B a B 8: b-B a B 9: b-B a B 10: b-B a B 11: c-C c C 12: c-C c C 13: c-C c C 14: c-C c C 15: c-C c C
两种方法都能高效实现需求,你可以根据是否需要复用索引来选择~
内容的提问来源于stack exchange,提问作者Grec001
相关产品推荐
相关产品推荐

