如何在data.table中按q、r、s分组后每组仅保留一行?
解决按指定列分组去重的问题
你遇到的问题是因为默认的unique()和错误的duplicated()用法没有针对目标分组列去重,下面给你几个data.table专属的简洁解决方案:
方法1:用unique()的by参数(推荐)
data.table的unique()函数支持指定by参数,直接按你要的分组列去重,每组保留首次出现的行:
unique(a, by = c("q", "r", "s"))
运行后会得到预期结果:
q r s t 1: 1 1 1 1 2: 1 1 3 2 3: 2 1 3 1 4: 2 1 1 2 5: 3 1 1 1 6: 3 1 3 2
方法2:分组后灵活选择行
如果需要更灵活的规则(比如取每组最后一行),可以用data.table的分组操作:
# 取每组第一行 a[, .SD[1], by = .(q, r, s)] # 取每组最后一行 a[, .SD[N], by = .(q, r, s)] # 更高效的取首行写法 a[, head(.SD, 1), by = .(q, r, s)]
为什么之前的方法无效?
unique(a)默认是对所有列进行去重,你的数据里t列每行都不一样,所以所有行都会被保留,达不到分组去重的效果。!duplicated(a$q,a$r,a$s)的写法错误,duplicated()的第一个参数需要是完整的列组合(比如数据框或data.table),正确写法应该是a[!duplicated(a[, .(q, r, s)])],虽然能得到结果,但不如data.table原生的unique(by=...)简洁直观。
内容的提问来源于stack exchange,提问作者Ricky
相关产品推荐
相关产品推荐

