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

如何在data.table中按year、field分组,去除两列顺序互换的重复行

去除data.table中肥料名称顺序互换的重复行

Stack Overflow上已有类似问题,但均不适用于我当前的data.table数据格式,因此发布此问题。

我的data.table数据如下:

year  field fert_name.x   yield.x fert_name.y   yield.y
 1: 2017 field1       fertA  7.875775       fertB 14.404673
 2: 2017 field1       fertA  7.875775       fertC 10.514350
 3: 2017 field1       fertB 14.404673       fertA  7.875775
 4: 2017 field1       fertB 14.404673       fertC 10.514350
 5: 2017 field1       fertC 10.514350       fertA  7.875775
 6: 2017 field1       fertC 10.514350       fertB 14.404673
 7: 2017 field2       fertA  9.089769       fertB 10.281055
 8: 2017 field2       fertA  9.089769       fertC 14.568333
 9: 2017 field2       fertB 10.281055       fertA  9.089769
10: 2017 field2       fertB 10.281055       fertC 14.568333
11: 2017 field2       fertC 14.568333       fertA  9.089769
12: 2017 field2       fertC 14.568333       fertB 10.281055
13: 2018 field1       fertA 12.883051       fertB  5.455565
14: 2018 field1       fertA 12.883051       fertC  9.566147
15: 2018 field1       fertB  5.455565       fertA 12.883051
16: 2018 field1       fertB  5.455565       fertC  9.566147
17: 2018 field1       fertC  9.566147       fertA 12.883051
18: 2018 field1       fertC  9.566147       fertB  5.455565
19: 2018 field2       fertA 13.830174       fertB 13.924190
20: 2018 field2       fertA 13.830174       fertC  9.533342
21: 2018 field2       fertB 13.924190       fertA 13.830174
22: 2018 field2       fertB 13.924190       fertC  9.533342
23: 2018 field2       fertC  9.533342       fertA 13.830174
24: 2018 field2       fertC  9.533342       fertB 13.924190

我需要按year和field分组,去除所有fert_name.x与fert_name.y顺序互换的重复行——例如行1与行3(fertA/fertB和fertB/fertA)、行2与行5(fertA/fertC和fertC/fertA)这类配对只保留一行。


数据集复现代码

library(data.table)
# 创建模拟数据
dat <- data.table(expand.grid(year=2017:2018,
                              field=c("field1","field2"),
                              fert_name=c("fertA","fertB","fertC"),
                              stringsAsFactors=F))
set.seed(123); yld <- runif(12, min=5, max=15)
dat$yield <- yld
(dat.m <- merge(dat, dat, by=c("year","field"), allow.cartesian=T)[fert_name.x != fert_name.y])

最优实现方案

利用data.table的分组筛选功能,直接在每个year+field组内保留fert_name.x字典序小于fert_name.y的行,这样每个肥料配对只会保留一行:

# 保留每个配对的唯一行
dat.unique <- dat.m[ , .SD[fert_name.x < fert_name.y], by = .(year, field)]

方案说明

  • 字符串的字典序比较(fertA < fertB < fertC)可以确保每个肥料配对(如fertA&fertB)只会留下fert_name.x在前的那一行,自动剔除反向的重复行。
  • 这种方式无需额外生成辅助列,直接在分组内筛选,效率很高,适合大规模数据集。
  • 处理后的结果会从24行缩减为12行(每个分组3个肥料,共C(3,2)=3个唯一配对,2年×2地块×3=12行)。

备选方案(生成唯一配对标识)

如果需要更灵活的配对判断,可以生成一个包含排序后肥料名称的辅助列,再通过去重实现:

# 生成排序后的配对标识
dat.m[, fert_pair := paste(pmin(fert_name.x, fert_name.y), pmax(fert_name.x, fert_name.y), sep = "-"), by = .(year, field)]
# 去重
dat.unique <- dat.m[!duplicated(fert_pair)]
# 可选:删除辅助列
dat.unique[, fert_pair := NULL]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 03:10:39