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

按id和var分组去重:保留出现频率最高的行(含平局处理)

解决按分组保留频率最高值的问题

嘿,针对你需要按id和var分组,对val执行去重并保留出现频率最高的行(频率相同时选字母/数字排序第一的)的需求,这里有两种简洁好用的R实现方式,完全匹配你的预期结果:

方法一:用dplyr(tidyverse风格,直观易读)

如果你平时习惯用tidyverse工具链,这种方式最容易理解:

library(dplyr)

# 你的示例数据
df <- data.frame( id = rep("a", 8), var = c(rep("b", 4), rep("c", 4)), val = c("d", "d", "d", "e", "f", "f", "g", "g") )

# 核心处理逻辑
result <- df %>%
  # 先按id、var、val分组,统计每个val的出现次数
  group_by(id, var, val) %>%
  tally() %>%
  # 按id、var分组后,先按次数降序排,次数相同则按val升序排
  arrange(id, var, desc(n), val) %>%
  # 每个(id,var)组只取第一行
  slice_head(n = 1) %>%
  # 去掉计数列,恢复原数据结构
  select(-n) %>%
  ungroup()

# 查看结果
print(result)

运行后输出和你的预期完全一致:

# A tibble: 2 × 3
  id    var   val  
  <chr> <chr> <chr>
1 a     b     d    
2 a     c     f    

方法二:用data.table(大数据场景更高效)

如果你的数据集规模很大,data.table的处理速度会比dplyr快不少,写法也很简洁:

library(data.table)

# 转换为data.table格式
setDT(df)

# 核心处理逻辑
result <- df[, .N, by = .(id, var, val)][, .SD[order(-N, val)[1]], by = .(id, var)][, -"N"]

# 查看结果
print(result)

输出同样符合预期。

逻辑说明

两种方法的核心思路是一致的:

  • 统计频率:先按id、var、val组合分组,计算每个val在对应组内的出现次数;
  • 排序筛选:在每个id+var的组内,优先按频率降序排列,频率相同的情况下按val的字母/数字顺序升序排列,然后取每组的第一行;
  • 清理结果:移除中间的计数列,得到你需要的最终结构。

这样处理既保证了保留频率最高的行,也解决了频率相同时的排序选择问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:52:41