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

按学生分组重置连续通过考试次数计数器的R语言实现

按学生分组计算连续通过考试次数的解决方案

针对你用R语言data.table处理考试数据时,需要按学生分组统计连续通过次数(遇到失败重置为0,新学生自动重置)的需求,修改原代码如下:

方法一:基于分段分组的实现

利用data.table的分组特性,在每个学生的子集中处理连续通过计数:

# 按id分组计算consec变量
my_data[, consec := {
  # 生成连续段的分组ID:每次遇到失败(results=0)就开启新分组
  group_id = c(0, cumsum(abs(diff(results == 0))))
  # 对每个分段生成计数:失败段全为0,通过段从1递增
  unlist(lapply(split(results, group_id), function(x) {
    if (x[1] == 0) rep(0, length(x))
    else seq_along(x)
  }))
}, by = id]

逻辑说明

  • by = id:强制每个学生的计算独立,新学生的计数自动从0开始重置
  • group_id:通过diff(results == 0)检测结果切换的位置,用cumsum生成连续段的唯一标识,确保失败后开启新的计数段
  • 分段处理:失败开头的分段直接填充0,通过开头的分段生成从1开始的递增序列,实现连续通过计数

运行后你的示例数据会得到如下结果:

id results date_exam_taken exam_number consec
1:  1       0      2002-10-06           1      0
2:  1       1      2003-07-21           2      1
3:  1       1      2003-10-15           3      2
4:  1       0      2005-07-21           4      0
5:  1       1      2014-08-22           5      1
6:  1       1      2015-09-11           6      2

方法二:遍历累积的简洁实现

如果觉得分段分组的写法复杂,也可以用遍历累积的方式实现,逻辑更直观:

# 遍历每个学生的记录计算连续通过次数
my_data[, consec := {
  temp_vec = integer(.N)
  for (i in seq_len(.N)) {
    temp_vec[i] = if (results[i] == 0) {
      0
    } else {
      if (i == 1) 1 else temp_vec[i-1] + 1
    }
  }
  temp_vec
}, by = id]

逻辑说明

  • 对每个学生的考试记录逐个遍历:
    • 若当前考试失败(results=0),则consec设为0
    • 若当前考试通过,且是该学生第一次考试,则consec设为1;否则在上一次的consec基础上加1
  • 同样通过by = id保证每个学生的计数独立重置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:20:26