计算两个日期区间重叠天数:入组180天与冬季时段的重叠计算
解决日期区间与冬季时段的重叠天数计算问题
问题描述
需要计算两个日期区间的重叠天数:
- 区间1:参与者入组日期(
enr_dte)至入组日期加180天(end_dte = enr_dte + days(180)) - 区间2:所有冬季时段(每年10月1日至次年5月31日)
现有代码仅在入组区间未覆盖夏季或未跨冬季年份时计算正确,其余情况会错误返回180天,需要修正。
问题根源
原代码仅固定了2021-10-01到2022/2023年5月31日的冬季区间,未考虑:
- 入组日期处于其他年份的情况
- 入组区间跨多个冬季时段的场景
- 夏季(6-9月)完全不重叠的逻辑
解决方案
使用lubridate处理日期,结合dplyr和purrr实现通用的重叠天数计算,自动适配所有年份和跨区间场景:
步骤1:加载依赖包
library(lubridate) library(dplyr) library(purrr)
步骤2:预处理数据,生成入组结束日期
# 确保日期格式正确,生成end_dte OMset <- OMset %>% mutate( enr_dte = ymd(enr_dte), end_dte = enr_dte + days(180) )
步骤3:定义重叠天数计算函数
该函数会自动生成所有与入组区间相关的冬季时段,逐一计算重叠部分后求和:
calculate_winter_overlap <- function(start_date, end_date) { # 生成所有可能涉及的冬季时段起始年份 winter_start_years <- seq(year(start_date) - 1, year(end_date)) # 构建每个冬季时段:Y年10月1日 至 Y+1年5月31日 winter_intervals <- tibble( winter_start = ymd(paste(winter_start_years, "10", "01", sep = "-")), winter_end = ymd(paste(winter_start_years + 1, "05", "31", sep = "-")) ) # 计算每个冬季时段与入组区间的重叠天数(包含两端日期) winter_intervals <- winter_intervals %>% mutate( overlap_start = pmax(winter_start, start_date), overlap_end = pmin(winter_end, end_date), overlap_days = ifelse(overlap_start <= overlap_end, as.numeric(overlap_end - overlap_start) + 1, 0) ) # 返回总重叠天数 sum(winter_intervals$overlap_days) }
步骤4:应用函数计算所有行的重叠天数
OMset <- OMset %>% mutate(overlap_days = map2_dbl(enr_dte, end_dte, calculate_winter_overlap))
测试验证
- 若入组日期为
2022-06-01,结束日期为2022-11-27,重叠天数应为58天(2022-10-01至2022-11-27) - 若入组日期为
2022-09-01,结束日期为2023-02-27,重叠天数应为150天(2022-10-01至2023-02-27) - 若入组日期为
2022-07-01,结束日期为2022-12-28,重叠天数为89天(2022-10-01至2022-12-28)
内容的提问来源于stack exchange,提问作者Rolvix Patterson
相关产品推荐
相关产品推荐

