使用ties.method="min"的R排名:分组观测数不同时的tidyverse实现
问题与简洁解决方案
背景与需求
- 数据包含2013-2023年季度观测,涉及A、B、C、D、E共5个类别
- 每个类别每年对应唯一值,但部分类别可能不覆盖全年所有季度(即同一年同一类别会有多个季度的重复值)
- 需要按年度为每个类别生成排名:最高值排第1,并列情况采用
rank(x, ties.method = "min")规则处理
之前的问题
- 按
year, quart分组排名:仅当各年度、类别的季度观测数完全相等时有效,观测数不均时结果错误 - 仅按
year分组排名:未处理同年度同类别多季度重复值的问题,排名结果不符合需求
无需中间对象的tidyverse实现
直接通过链式操作完成去重+排名,不需要额外创建中间表或做连接:
示例数据构造
library(tidyverse) set.seed(123) # 生成带重复值、缺失季度的模拟数据 df <- expand_grid(year = 2013:2023, quart = 1:4, category = LETTERS[1:5]) %>% mutate(value = case_when( category == "A" ~ 90, category == "B" ~ sample(c(85,85,90), n(), replace = TRUE), category == "C" ~ 80, TRUE ~ sample(70:85, n(), replace = TRUE) )) %>% slice_sample(prop = 0.8) # 随机删行模拟类别不全的情况
核心处理代码
df_ranked <- df %>% # 保留每个年度-类别的唯一行(值相同,任意一行均可) distinct(year, category, .keep_all = TRUE) %>% # 按年度分组计算排名,-value实现降序,指定min处理并列 group_by(year) %>% mutate(rank = rank(-value, ties.method = "min")) %>% ungroup() # 查看整理后的结果 df_ranked %>% select(year, category, value, rank) %>% arrange(year, rank)
代码说明
distinct(year, category, .keep_all = TRUE):自动去重,确保每个年度-类别组合只保留一行,同时保留所有列信息rank(-value, ties.method = "min"):通过取负值实现降序排名(最高值排第1),ties.method = "min"保证并列值取最小排名
内容的提问来源于stack exchange,提问作者user16822752
相关产品推荐
相关产品推荐

