如何用dplyr::case_when/if_else生成含多区间双条件的3月随访列
R语言:基于start_date生成3个月随访状态列
原始数据框
df <- data.frame( id = c(1:6), start_date = c('Mar-22','Feb-22','Jan-22','Dec-21','Nov-21','Oct-21'), `Jan-22` = c(NA,NA,1,0,0,1), `Feb-22` = c(NA,1,1,0,0,1) )
需求说明
需要在dplyr::mutate中生成新列3_month_followup,规则如下:
- 计算
start_date后3个月对应的月份,匹配数据框中对应的月份列 - 如果该月份列存在且值为1,标记为
yes;如果存在但值为0,标记为no;如果该月份列不存在(无后续3个月记录),标记为NA
当前仅能实现单个日期的判断,需扩展到所有情况,最终预期结果:
# id start_date Jan-22 Feb-22 3_month_followup # 1 1 Mar-22 NA NA <NA> # 2 2 Feb-22 NA 1 <NA> # 3 3 Jan-22 1 1 <NA> # 4 4 Dec-21 0 0 <NA> # 5 5 Nov-21 0 0 no # 6 6 Oct-21 1 1 yes
解决方案
核心思路是先将字符型日期转为可计算的日期格式,生成目标月份列名后逐行匹配对应值,需用到lubridate处理日期:
library(dplyr) library(lubridate) df_result <- df %>% rowwise() %>% mutate( # 转换日期并计算3个月后的目标月份(匹配现有列名格式) target_month = format(ym(start_date) %m+% months(3), "%b-%y"), # 判断目标月份列是否存在 col_exists = target_month %in% colnames(df), # 多条件生成结果列 3_month_followup = case_when( !col_exists ~ NA_character_, col_exists & pull(cur_data(), target_month) == 1 ~ "yes", col_exists & pull(cur_data(), target_month) == 0 ~ "no", TRUE ~ NA_character_ ) ) %>% ungroup() %>% # 移除中间辅助列(可选) select(-target_month, -col_exists) # 查看结果 print(df_result)
代码解释
- 日期处理:用
ym()将字符型日期转为标准年月格式,%m+% months(3)避免跨年度/月末的日期计算误差,再转成和现有列名一致的%b-%y格式。 - 行级匹配:
rowwise()确保逐行处理,pull(cur_data(), target_month)动态提取当前行对应目标月份的列值。 - 条件判断:
case_when()按优先级依次判断列是否存在、值是否为1/0,生成对应标记。
内容的提问来源于stack exchange,提问作者M3Lba
相关产品推荐
相关产品推荐

