R语言多日期变量筛选:生成符合特定时间条件的精神病病例子集
R语言筛选符合日期条件的病例子集
需求回顾
需要从包含隔离记录的精神病患者病例数据集中筛选两类病例:
- 无任何隔离记录的病例
- 首次隔离日期
seclusion_date1晚于2019-06-30,且所有隔离结束日期(seclusion_enddate1、seclusion_enddate2…)早于2020-05-01的病例
现有代码问题分析
- 自定义函数报错:
any_of()和starts_with()是dplyr包中tidyselect语法的选择函数,必须在select()、across()等dplyr函数内部使用,不能直接和数据集拼接,因此你的自定义函数写法会触发错误。 - 循环代码无效:循环中每次都重新赋值
cohort_2_before,且用paste0()生成的字符串无法直接作为变量在subset()的条件中引用,导致筛选逻辑失效,最终得到0行结果。
解决方案
推荐使用dplyr包处理多列筛选逻辑,代码更简洁易读,适合新手:
步骤1:加载包并转换日期类型
首先确保日期列是Date类型(字符类型的日期比较会出错):
library(dplyr) # 转换所有隔离日期和结束日期列为Date类型 WMdata <- WMdata %>% mutate( across(starts_with("seclusion_date"), as.Date), across(starts_with("seclusion_enddate"), as.Date) )
步骤2:筛选符合条件的子集
cohort_2_before <- WMdata %>% filter( # 条件1:无隔离记录(假设无隔离时seclusion_date1为NA) is.na(seclusion_date1) | # 条件2:首次隔离日期符合,且所有隔离结束日期符合要求 (seclusion_date1 >= as.Date("2019-07-01") & across(starts_with("seclusion_enddate"), ~ is.na(.) | . <= as.Date("2020-04-30"))) )
across(starts_with("seclusion_enddate"), ...)会对所有以seclusion_enddate开头的列应用条件is.na(.)是为了兼容只有n次隔离、后续结束日期列为空的情况,这类空值不影响筛选
如果你偏好Base R写法
# 获取所有隔离结束日期列的列名 enddate_cols <- grep("^seclusion_enddate", colnames(WMdata), value = TRUE) date_cols <- c(grep("^seclusion_date", colnames(WMdata), value = TRUE), enddate_cols) # 转换日期列为Date类型 WMdata[, date_cols] <- lapply(WMdata[, date_cols], as.Date) # 定义筛选条件 no_seclusion <- is.na(WMdata$seclusion_date1) valid_seclusion <- !is.na(WMdata$seclusion_date1) & WMdata$seclusion_date1 >= as.Date("2019-07-01") & apply(WMdata[, enddate_cols], 1, function(row) all(is.na(row) | row <= as.Date("2020-04-30"))) # 生成子集 cohort_2_before <- WMdata[no_seclusion | valid_seclusion, ]
内容的提问来源于stack exchange,提问作者Iokaste
相关产品推荐
相关产品推荐

