统计考试结果序列频率:修正data.table代码错误
问题排查与修正方案
常见踩坑点分析
你遇到的统计错误大概率是这几个原因:
- 数据没按学生+考试顺序排序:
shift是按行顺序取数,如果数据乱序,会跨学生拿到别人的考试结果,直接导致统计错误。 - 没排除无效行:前两次考试(比如第1、2次)根本没有“前两次”的历史数据,对应的
prev1/prev2是NA,这些行不能参与统计。 - shift分组错了:没按
student_id分组做shift,导致不同学生的考试结果混在一起计算。
修正后的完整代码
library(data.table) # 模拟你的数据结构(可替换为实际数据) dt <- data.table( student_id = rep(1:2, each=4), exam_order = rep(1:4, 2), exam_result = c(1,1,1,0, 1,1,0,1) ) # 核心前提:按学生+考试顺序排序 setorder(dt, student_id, exam_order) # 按学生分组生成前1次、前2次考试结果 dt[, `:=`( prev1 = shift(exam_result, n=1), prev2 = shift(exam_result, n=2) ), by = student_id] # 筛选符合条件的行,统计当前考试通过次数 final_result <- dt[ !is.na(prev1) & !is.na(prev2) & prev1 == 1 & prev2 == 1, .(count_pass = sum(exam_result == 1)), by = student_id ] print(final_result)
预期输出
student_id count_pass 1: 1 1 2: 2 0
(解释:学生1的第3次考试满足前两次都通过且本次通过,计数1;学生2只有第3次考试满足前两次通过,但本次失败,第4次考试的前两次是第2、3次(第3次失败),不满足条件,所以计数0,完全符合预期)
关键修正点说明
setorder排序:强制数据按学生和考试先后顺序排列,保证shift取到的是同学生的历史考试数据,不会串到其他学生。by=student_id做shift:每个学生的历史数据独立计算,彻底避免跨学生的错误取值。- 过滤NA和无效条件:先把没有前两次数据的行去掉,再只保留前两次都通过的行,最后统计这些行里当前考试通过的次数,逻辑完全闭环。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

