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

R data.table按ID分组处理:年份列满足条件时仅保留最大值其余置零

data.table分组按条件修改列值实现方案

不需要嵌套for循环,直接用data.table原生的分组+列迭代语法即可高效实现需求,代码如下:

完整代码

library(data.table)
# 构造示例数据
data = data.table(
  ID = c("a1", "a2", "a2", "a1", "a2", "a1", "a1"),
  "2018" = c(3,5,11,3,9,22,6),
  "2019" = c(3,5,6,21,1,4,0),
  "2020" = c(0,4,13,9,16,7,9),
  "2021" = c(4,0,3,8,5,4,6)
)
# 提取所有年份列(排除ID分组列)
year_cols <- setdiff(names(data), "ID")
# 按ID分组处理每一列
data[, (year_cols) := lapply(.SD, function(x) {
  col_max <- max(x)
  # 存在≥10的数值时仅保留最大值,其余置0,否则不修改
  fifelse(col_max >= 10, fifelse(x == col_max, x, 0), x)
}), by = ID, .SDcols = year_cols]
# 验证结果和预期一致
solution <- data.table(
  ID = c("a1", "a2", "a2", "a1", "a2", "a1", "a1"),
  "2018" = c(0,0,11,0,0,22,0),
  "2019" = c(0,5,6,21,1,0,0),
  "2020" = c(0,0,0,9,16,7,9),
  "2021" = c(4,0,3,8,5,4,6)
)
identical(data, solution) # 返回TRUE

逻辑说明

  • 先用setdiff提取所有需要处理的年份列,避免硬编码列名
  • 按ID字段分组,通过.SDcols指定仅对年份列做操作
  • 对每个分组的每一列单独处理:
    • 先计算当前列的最大值,判断是否≥10
    • 若满足条件,用fifelse把所有不等于最大值的元素置0,仅保留最大值
    • 若不满足条件,直接返回原列数据

特殊场景适配

如果同一个ID、同一年份列下存在多个相等的最大值且≥10,上述代码会保留所有最大值。如果仅需要保留第一个出现的最大值,可把函数内的判断逻辑修改为:

fifelse(col_max >= 10, fifelse(x == col_max & cumsum(x == col_max) == 1, x, 0), x)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:18:01