如何用R筛选与目标日期区间交集≥180天的吸烟案例
问题:筛选符合特定吸烟时长条件的ID
数据集
library(tidyverse) library(lubridate) df <- data.frame( ID = 1:10, start_date_smoking = c("28/06/2011", "27/07/2012", "09/04/2003", "01/07/2013", "28/06/2011", "01/09/2013", "01/09/2013", "30/08/2014", "01/09/2013", "01/09/2013"), end_date_smoking = c("01/01/2017", "01/01/2017", "01/01/2017", "01/01/2017", "01/09/2013", "01/09/2013", "02/09/2013", "01/01/2017", "31/08/2014", "31/08/2014") ) df <- df %>% mutate( start_date_smoking = dmy(start_date_smoking), end_date_smoking = dmy(end_date_smoking), days = time_length(difftime(end_date_smoking, start_date_smoking), "days") )
需求说明
- 筛选吸烟区间与2013-09-01至2014-08-31有交集的记录
- 且该目标时段内的吸烟时长至少180天
- 期望结果ID:1、2、3、4、9、10
- 需包含ID1这类早于目标时段开始吸烟的案例,排除ID8这类目标时段内时长不足180天的案例
尝试的错误代码
start_range <- dmy("01/09/2013") end_range <- dmy("31/08/2014") df %>% filter(days >= 180 & (start_date_smoking >= start_range & start_date_smoking <= end_range) | (end_date_smoking >= start_range & end_date_smoking <= end_range) | (start_date_smoking <= start_range & end_date_smoking >= end_range))
解决方案
你的代码存在两个核心问题:
- 错误使用了全局吸烟周期的
days >=180,而非目标时段内的重叠时长 - 交集判断逻辑冗余,且未精确计算重叠天数
针对1500万行的大数据集,以下方案采用向量化运算,效率极高:
# 定义目标时段 start_range <- dmy("01/09/2013") end_range <- dmy("31/08/2014") # 计算重叠时长并筛选 result <- df %>% mutate( # 取吸烟起始与目标起始的较晚值作为重叠起始 overlap_start = pmax(start_date_smoking, start_range), # 取吸烟结束与目标结束的较早值作为重叠结束 overlap_end = pmin(end_date_smoking, end_range), # 计算有效重叠天数:无交集时设为0 overlap_days = time_length(difftime(overlap_end, overlap_start), "days") %>% pmax(0) ) %>% filter(overlap_days >= 180) %>% select(ID, overlap_days) # 可选,保留需要的列 # 输出结果 result
逻辑说明
pmax()和pmin()是向量化函数,能批量计算每个记录的重叠区间,避免循环,适配大数据量- 重叠天数为0时说明无交集,自动被排除
- 最终筛选仅保留目标时段内吸烟时长≥180天的ID,完全符合预期结果:ID1、2、3、4、9、10
内容的提问来源于stack exchange,提问作者allen.joseph
相关产品推荐
相关产品推荐

