如何用R语言结合lag函数按时间条件标记待选拭子样本?
解决方案
需求回顾
按studyID分组,逐行筛选未选中拭子(swabbed=1且selected=0):
- 若当前样本距离上一个已选中样本(包括初始
selected=1的样本和新标记的selected_new=1的样本)的时间在10-21天范围内,标记selected_new=1 - 新标记的样本会成为后续行判断的基准
核心问题
lag()函数无法动态跟踪更新后的选中状态,只能固定取上一行的特定值,因此需要用累积计算逐行维护最近选中的日期。
完整代码
library(tidyverse) # 修正示例数据的selected列类型(字符转数值) df <- df %>% mutate(selected = as.numeric(selected)) # 按参与者分组处理 df_processed <- df %>% group_by(studyID) %>% mutate( # 逐行累积更新最近选中的日期 last_selected = accumulate(row_number(), .init = first(date[selected == 1]), ~{ current_row <- cur_data()[.y, ] # 优先判断当前行是否是符合条件的未选中拭子,是则更新基准日期 if (current_row$swabbed == 1 && current_row$selected == 0 && current_row$date - .x >= 10 && current_row$date - .x <= 21) { current_row$date } else { # 若当前行是原本已选中的样本,也更新基准日期;否则保持原基准 if (current_row$selected == 1) current_row$date else .x } }) %>% tail(-1), # 移除初始化的额外值,匹配数据行数 # 生成最终的selected_new标记 selected_new = case_when( swabbed == 1 && selected == 0 && date - last_selected >= 10 && date - last_selected <= 21 ~ 1, TRUE ~ 0 ) ) %>% ungroup()
代码说明
- 分组处理:
group_by(studyID)确保每个参与者的判断独立进行 - 累积跟踪基准日期:
accumulate()函数逐行迭代,初始值设为该参与者第一个selected=1样本的日期- 每次迭代时,根据当前行的状态更新基准日期:符合条件的未选中拭子或原本已选中的样本都会成为新的基准
- 标记新选中样本:用
case_when根据基准日期差和拭子状态生成selected_new列
示例验证
针对提供的示例数据,处理后:
- day=13(date=2022-11-30)的样本:距离初始选中的day0(2022-11-17)为13天,符合10-21天范围,
selected_new=1 - day=17(date=2022-12-04)的样本:距离最新基准日期(2022-11-30)仅4天,不符合范围,
selected_new=0
完全符合预期结果。
内容的提问来源于stack exchange,提问作者tlo
相关产品推荐
相关产品推荐

