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

如何用data.table实现同分同排名且跳过占用位次的真实排名?

用data.table实现同分同排名且跳过占用位次的排名

嘿,我来帮你搞定这个排名需求!你想要的这种同分同排名、同时跳过相同成绩占用位次的排名(也叫竞争排名),确实不能直接用.GRP——因为.GRP只会生成连续的分组序号。不过用data.table可以通过结合分组大小和累计求和轻松实现,下面给你两种简洁的方法:

方法一:先生成排名键再合并

这种方法逻辑清晰,先单独计算每个等级对应的排名,再关联回原数据表:

library(data.table)
DT <- data.table(GRADE = c("A","B","B","C",rep("D",4)))

# 1. 按等级分组统计人数,排序后计算每个等级的排名
rank_key <- DT[, .N, by = GRADE][order(GRADE)][, RANK := cumsum(shift(N, fill = 0)) + 1]

# 2. 将排名关联回原数据表
DT[rank_key, on = "GRADE", RANK := i.RANK]

# 查看结果
DT

运行后得到的结果完全符合你的预期:

GRADE RANK
1:     A    1
2:     B    2
3:     B    2
4:     C    4
5:     D    5
6:     D    5
7:     D    5
8:     D    5

方法二:链式一步完成

如果喜欢更紧凑的写法,可以把逻辑放到一个链式操作里,不用单独生成中间表:

DT[, RANK := {
    # 内部计算每个等级的排名
    rank_dt <- .SD[, .N, by = GRADE][order(GRADE)][, RANK := cumsum(shift(N, fill = 0)) + 1]
    # 匹配当前行的等级对应的排名
    rank_dt[.SD, on = "GRADE", x.RANK]
}]

关键逻辑解释

这里的核心是cumsum(shift(N, fill = 0)) + 1:

  • .N是每个等级的学生人数
  • shift(N, fill = 0)会把每个等级的人数往前偏移一位,第一个等级的偏移值填充为0
  • cumsum()计算前面所有等级的总人数,加1就是当前等级的起始排名(也就是该等级所有学生的排名)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:35:08