在R中基于分组多条件排序生成最终排名列的技术问题
在R中按多条件分组生成统一排名列的解决方案
原始数据表
| team | tournament | pool | year | sets ratio | points ratio |
|---|---|---|---|---|---|
| team 1 | tournament 1 | a | 2011 | 3.00 | 0.89 |
| team 2 | tournament 1 | a | 2011 | 1.00 | 1.57 |
| team 3 | tournament 1 | a | 2011 | 1.50 | 1.11 |
| team 4 | tournament 1 | b | 2011 | 1.33 | 1.05 |
需求说明
需要新增final_standing列,按pool、year、tournament分组后,每组内按以下规则排名:
- 优先按
sets ratio降序排列 - 当
sets ratio相同时,按points ratio降序排列
错误代码分析
你之前用order的方式存在两个问题:
- 列名包含空格时未用反引号包裹(
sets ratio应写为`sets ratio`) order()返回的是排序后的行索引位置,不是直接的排名值,因此无法得到预期的排名结果
另外他人推荐的aggregate代码仅能分别生成sets ratio和points ratio的单独排名,无法实现你需要的统一优先级排名。
正确解决方案
使用dplyr的分组排序+行号生成的方式,逻辑直观且结果准确:
library(dplyr) # 加载数据后执行以下代码 data <- data %>% # 按指定字段分组 group_by(pool, year, tournament) %>% # 按规则排序(组内排序) arrange(desc(`sets ratio`), desc(`points ratio`), .by_group = TRUE) %>% # 生成组内排名 mutate(final_standing = row_number()) %>% # 取消分组 ungroup()
运行结果
| team | tournament | pool | year | sets ratio | points ratio | final_standing |
|---|---|---|---|---|---|---|
| team 1 | tournament 1 | a | 2011 | 3.00 | 0.89 | 1 |
| team 3 | tournament 1 | a | 2011 | 1.50 | 1.11 | 2 |
| team 2 | tournament 1 | a | 2011 | 1.00 | 1.57 | 3 |
| team 4 | tournament 1 | b | 2011 | 1.33 | 1.05 | 1 |
如果需要处理并列排名(比如两个队伍的sets ratio和points ratio完全相同),可以将row_number()替换为min_rank()或dense_rank(),根据你的并列排名规则选择:
min_rank():并列队伍获得相同排名,后续排名跳过对应数量(如并列第1,下一个是第3)dense_rank():并列队伍获得相同排名,后续排名连续(如并列第1,下一个是第2)
内容的提问来源于stack exchange,提问作者the_special_none
相关产品推荐
相关产品推荐

