基于R实现测试终止规则:8题窗口内错6题后后续值置0
问题:按规则修正实验测试数据
实验测试规则:当参与者在**任意连续8道题的窗口内答错6道题(答错标记为0)**时,必须停止测试。但部分实验人员未按规则终止测试,现需用R语言逐行处理每个参与者的测试数据,找到触发终止规则的位置,并将该位置之后的所有测试值置为0。
可复现测试数据:
df <- structure(list(Participant_ID = c("E01P01", "E01P02", "E01P03", "E01P04", "E01P05", "E01P06", "E01P07", "E01P08", "E02P01", "E02P02" ), A2 = c(1, 1, 1, 0, 0, 1, 1, 1, 1, 1), A3 = c(1, 1, 0, 0, 0, 1, 0, 0, 0, 0), B1 = c(1, 1, 1, 0, 0, 1, 0, 0, 1, 1), B2 = c(1, 1, 1, 1, 1, 1, 0, 0, 0, 1), C3 = c(1, 0, 0, 1, 0, 1, 0, 0, 0, 1), C4 = c(1, 0, 0, 0, 0, 1, 0, 0, 1, 1), D1 = c(1, 0, 0, 0, 0, 1, 0, 0, 0, 0), D3 = c(1, 1, 1, 1, 0, 0, 1, 0, 0, 1), E1 = c(1, 0, 0, 0, 0, 1, 0, 0, 0, 1), E3 = c(1, 1, 0, 1, 0, 1, 0, 0, 0, 0), F1 = c(1, 0, 0, 0, 1, 0, 0, 1, 0, 0), F4 = c(1, 1, 1, 1, 0, 1, 0, 1, 1, 0), G1 = c(1, 0, 0, 0, 0, 1, 0, 0, 0, 1), G2 = c(0, 0, 0, 0, 1, 1, 1, 0, 1, 1)), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"))
解决方案
处理逻辑
- 针对每个参与者的答题数据(排除ID列),用滑动窗口统计连续8题中的错题数量
- 定位第一个满足「窗口内错题≥6」的位置,以此作为测试终止点
- 将终止点及之后的所有答题值设为0
- 保留原始参与者ID,整合处理后的数据
R代码实现
library(dplyr) library(purrr) library(slider) # 定义单个参与者数据处理函数 process_participant <- function(row) { # 提取答题数值,排除ID列 answers <- row[-1] %>% as.numeric() total_items <- length(answers) # 题目数量不足8道,直接返回原数据 if(total_items < 8) return(row) # 滑动窗口统计每个8题窗口内的错题数 error_counts <- slider::slide_int(answers, ~sum(.x == 0), .before = 7, .complete = TRUE) # 找到第一个触发终止规则的位置 trigger_index <- which(error_counts >= 6)[1] # 若找到触发点,将之后所有值置为0 if(!is.na(trigger_index)) { answers[trigger_index:total_items] <- 0 } # 把处理后的数据放回原行结构 row[-1] <- answers return(row) } # 逐行处理所有数据,生成修正后的数据集 corrected_df <- df %>% purrr::pmap_dfr(process_participant) # 查看修正结果 print(corrected_df)
代码说明
slider::slide_int用来创建滑动窗口:.before = 7表示每个窗口包含当前题和前7题,刚好8道;.complete = TRUE确保只统计完整的8题窗口which(error_counts >= 6)[1]定位第一个触发规则的窗口位置,也就是测试该停止的点pmap_dfr逐行应用处理函数,自动将结果整合成数据框
内容的提问来源于stack exchange,提问作者Adrianne Perry
相关产品推荐
相关产品推荐

