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

R dplyr按组求最大值后筛选Top3分组并添加布尔标识列

R语言按分组最大值筛选Top3分组并生成标识列

现有数据

示例dataframe构造代码如下:

df <- structure(list(id = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 
4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 
6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9), year = c("2017", "2018", 
"2019", "2020", "2021", "2022", "2023", "2024", "2025", "2026", 
"2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", 
"2025", "2026", "2017", "2018", "2019", "2020", "2021", "2022", 
"2023", "2024", "2025", "2026", "2017", "2018", "2019", "2020", 
"2021", "2022", "2023", "2024", "2025", "2026", "2017", "2018", 
"2019", "2020", "2021", "2022", "2023", "2024", "2025", "2026", 
"2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", 
"2025", "2026", "2017", "2018", "2019", "2020", "2021", "2022", 
"2023", "2024", "2025", "2026", "2017", "2018", "2019", "2020", 
"2021", "2022", "2023", "2024", "2025", "2026", "2017", "2018", 
"2019", "2020", "2021", "2022", "2023", "2024", "2025", "2026"
), volume = c(0.0013, 0.0013, 0.0012579, 0.0011895, 0.0011421, 
0.0010842, 0.0010211, 0.0010158, 0.00099474, 0.00092632, 0.07878, 
0.078791, 0.077295, 0.076638, 0.075538, 0.074468, 0.074776, 0.074051, 
0.071706, 0.068056, 0.023269, 0.023011, 0.022374, 0.021962, 0.021408, 
0.020949, 0.020811, 0.020354, 0.019309, 0.018042, 0.0004, 0.0004, 
0.00038421, 0.00035263, 0.00033158, 0.00032105, 0.00026842, 0.00028421, 
0.00026842, 0.00024211, 0.0002, 0.0001, 0.00011579, 0, 0, 0, 
0, 0, 0, 0, 0.028422, 0.028361, 0.027768, 0.027501, 0.027029, 
0.02651, 0.026588, 0.026209, 0.025094, 0.023391, 0.0001, 0.0001, 
0, 0, 0, 0, 0, 0, 0, 0, 0.0047, 0.0047158, 0.0048368, 0.0048316, 
0.0049263, 0.0049737, 0.0049947, 0.0051684, 0.0052526, 0.0051842, 
0.0106, 0.010389, 0.010279, 0.010005, 0.0098421, 0.0096368, 0.0094053, 
0.0093368, 0.0092526, 0.0089316)), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -90L))

数据预览:

# A tibble: 6 × 3
     id year   volume
  <dbl> <chr>   <dbl>
1     1 2017  0.0013 
2     1 2018  0.0013 
3     1 2019  0.00126
4     1 2020  0.00119
5     1 2021  0.00114
6     1 2022  0.00108

需求说明

  • 数据基础属性:id列共9个不同取值,每个id对应10条年度记录
  • 计算规则:
    • 按id分组,计算每个分组内volume列的最大值
    • 仅对比各分组的volume最大值,筛选出最大值排名前3的分组
    • 支持新增inTop3布尔列,标记对应id所属分组是否属于Top3分组
      注意:对比维度为分组级别的最大值,不对比单条记录数值,无需考虑分组内是否存在全局Top3的单条记录
  • 当前已完成代码(仅实现分组最大值计算):
df %>% 
  group_by(id) %>% 
  mutate(
    m = max(volume)
  ) 

实现方案

在现有分组计算的基础上,直接对分组最大值做降序排名,判断排名是否≤3即可,不需要解除分组操作。

1. 生成带inTop3标识的完整数据集

library(dplyr)

df_with_flag <- df %>% 
  group_by(id) %>% 
  mutate(
    group_max = max(volume), # 计算分组内volume最大值,即原有代码中的m
    inTop3 = dense_rank(desc(group_max)) <= 3 # 按最大值降序排名,前3标记为TRUE
  ) %>%
  ungroup()

函数说明:这里使用dense_rank处理并列情况,若多个分组最大值相同,排名不会跳号,并列的分组都会被纳入Top3范围;如果需要严格取3个分组(并列时按顺序取),可以替换为row_number。

2. 直接筛选Top3分组的所有记录

如果不需要保留全量数据,直接在上述逻辑后加筛选即可:

df_top3 <- df %>% 
  group_by(id) %>% 
  mutate(group_max = max(volume)) %>%
  filter(dense_rank(desc(group_max)) <= 3) %>%
  ungroup()

结果验证

针对提供的示例数据,各id的分组volume最大值排序为:

  • id=2:0.078791(第1名)
  • id=6:0.028422(第2名)
  • id=3:0.023269(第3名)
    以上3个id对应的所有记录inTop3值为TRUE,其余id对应记录为FALSE,完全符合需求规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 09:39:20