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

如何基于data.table计算30天窗口内学生各时间点的成绩排名?

计算每个学生在30天时间窗口内的成绩排名

根据你提供的示例数据和需求,我整理了两种常见场景的实现方案,你可以根据实际需要选择:

方案1:每个学生自身历史30天内的成绩排名

这个方案只关注当前学生在自身过去30天内的成绩,对当前成绩做降序排名(排名从1开始,同分取最小排名),完美匹配你示例中Rob的Rank结果:

library(data.table)
df <- fread('
Name Score Date Rank
John 42 1/1/2018 3
Rob 85 12/31/2017 2
Rob 89 12/26/2017 1
Rob 57 12/24/2017 1
Rob 53 08/31/2017 1
Rob 72 05/31/2017 2
Kate 87 12/25/2017 1
Kate 73 05/15/2017 1
')
df[, Date := as.Date(Date, format="%m/%d/%Y")]

# 按姓名分组,计算自身30天窗口内的排名
df <- df[order(Name, Date)]
df[, Rank_self := sapply(.I, function(i) {
  current_date <- Date[i]
  current_score <- Score[i]
  # 筛选同学生30天内的所有成绩
  window_scores <- Score[Date >= current_date - 30 & Date <= current_date]
  # 降序排名,ties.method控制同分处理逻辑
  rank(-window_scores, ties.method = "min")[which(Score == current_score & Date == current_date)]
}), by = Name]

print(df)

运行后你会看到,Rob在2017-12-31的85分,在他自己的30天窗口(包含57、89、85三个分数)中排名第2,和你给出的示例Rank完全一致。

方案2:所有学生在30天窗口内的成绩排名

如果需要把所有学生的成绩都纳入30天窗口,计算当前成绩在全局范围内的排名,代码如下:

# 计算全局30天窗口内的排名
df <- df[order(Date)]
df[, Rank_global := sapply(.I, function(i) {
  current_date <- Date[i]
  current_score <- Score[i]
  # 筛选所有学生30天内的成绩
  window_scores <- df[Date >= current_date - 30 & Date <= current_date, Score]
  # 降序排名
  rank(-window_scores, ties.method = "min")[which(window_scores == current_score & df[Date >= current_date - 30 & Date <= current_date, Date] == current_date)]
})]

print(df)

这个方案下,Rob在2017-05-31的72分,会和Kate在2017-05-15的73分一起参与排名,最终得到Rank2,和你示例中的值匹配。

优化说明:大数据集高效实现

如果你的数据量较大,上面的sapply方法效率会偏低,推荐用data.table的非等连接来优化:

# 高效非等连接实现全局排名
df[, Date_start := Date - 30]
rank_df <- df[df, on = .(Date >= Date_start, Date <= Date), allow.cartesian = TRUE][
  , .(Score, i.Score, i.Date), by = .EACHI][
  , rank(-Score, ties.method = "min"), by = i.Date][
  , .(Date = i.Date, Rank_global = V1)]
df <- df[rank_df, on = .(Date)]

这种方式利用了data.table的向量化操作,处理大规模数据时速度会快很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:44:04