基于匹配向量创建访视日期列:寻求R语言高效解决方案
优化研究访视日程生成的简洁方案
我需要给研究参与者模拟访视日程,手里有包含参与者信息和首次访视日期的dataframe,目标是生成后续各访视的日期列。不同研究组的访视间隔存在单独的向量中,目前用dplyr的case_when实现需求,但访视和组数量较多时代码繁琐重复,想要更稳健、简洁的解决方案。
原实现代码示例:
library(dplyr) # set up schedules arm1 <- c(0, 14, 28) arm2 <- c(0, 14, 19, 180) arm3 <- c(0, 14, 28, 32) # simulate dataframe for 30 participants d0 <- data.frame( ids = seq(1:30), studyarm = rep(c("arm1", "arm2", "arm3"), 10), date_visit1 = rep(seq(as.Date("2024-06-01"), as.Date("2024-06-10"), by = 1))) # add visit dates depending on arm d1 <- d0 %>% mutate( date_visit2 = case_when( studyarm == "arm1" ~ date_visit1 + arm1[2], studyarm == "arm2" ~ date_visit1 + arm2[2], studyarm == "arm3" ~ date_visit1 + arm3[2] ), date_visit3 = case_when( studyarm == "arm1" ~ date_visit1 + arm1[3], studyarm == "arm2" ~ date_visit1 + arm2[3], studyarm == "arm3" ~ date_visit1 + arm3[3] ), date_visit4 = case_when( studyarm == "arm1" ~ date_visit1 + arm1[4], # correctly returns NA studyarm == "arm2" ~ date_visit1 + arm2[4], studyarm == "arm3" ~ date_visit1 + arm3[4] ) )
方案一:用结构化参考表实现(易维护)
把各组访视间隔整理成结构化的数据框,通过连接和重塑生成所有访视日期,新增组别或访视只需修改参考表,无需调整后续逻辑:
library(dplyr) library(tidyr) # 1. 构建访视间隔参考表 schedule_ref <- tibble( studyarm = c("arm1", "arm1", "arm1", "arm2", "arm2", "arm2", "arm2", "arm3", "arm3", "arm3", "arm3"), visit_num = c(1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4), days_since_baseline = c(0, 14, 28, 0, 14, 19, 180, 0, 14, 28, 32) ) # 2. 生成所有访视日期并转为宽格式 d1 <- d0 %>% left_join(schedule_ref, by = "studyarm") %>% mutate( visit_date = date_visit1 + days_since_baseline, visit_col = paste0("date_visit", visit_num) # 生成列名 ) %>% select(ids, studyarm, date_visit1, visit_col, visit_date) %>% pivot_wider( names_from = visit_col, values_from = visit_date, values_fill = NA # 缺失访视填NA )
方案二:用命名列表+rowwise实现(更简洁)
将各组间隔存入命名列表,通过行运算批量生成访视日期列,代码更紧凑:
library(dplyr) # 1. 用命名列表存储各组访视间隔 arm_schedules <- list( arm1 = c(0, 14, 28), arm2 = c(0, 14, 19, 180), arm3 = c(0, 14, 28, 32) ) # 2. 确定最大访视数,生成列名 max_visits <- max(lengths(arm_schedules)) visit_cols <- paste0("date_visit", 1:max_visits) # 3. 批量生成访视日期 d1 <- d0 %>% rowwise() %>% mutate(visit_dates = list(date_visit1 + arm_schedules[[studyarm]])) %>% # 按组生成所有访视日期 ungroup() %>% mutate(!!!set_names(visit_dates, visit_cols)) %>% # 拆分列表为多列 select(-visit_dates)
优势对比
- 避免了原方法中重复编写
case_when的冗余代码,减少出错概率 - 扩展性强:新增研究组或访视时,只需修改参考表/命名列表,无需改动核心逻辑
- 代码更易读,结构清晰,便于后期维护
内容的提问来源于stack exchange,提问作者gxq9
相关产品推荐
相关产品推荐

