如何在R中合并不同间隔的相邻日期序列并衔接首尾?
Base R 优雅实现方案
步骤1:定义初始日期与各阶段参数
先明确首次手术日期,以及每个阶段的时间间隔和截止节点:
# 首次手术日期(1967年初冬约2月初) initial_start <- as.Date("1967-02-01") # 各阶段参数:每个元素为列表,包含间隔(by)和截止日期(to) phase_params <- list( list(by = "10 days", to = as.Date("1967-05-31")), # 第一阶段:每10天到1967年5月 list(by = "3 months", to = as.Date("1968-12-31")), # 第二阶段:每3个月到1968年底 list(by = "1 year", to = as.Date("1972-08-31")) # 第三阶段:每年一次到1972年升学前(假设8月底) )
步骤2:用Reduce连贯生成所有阶段序列
Reduce可以自动迭代每个阶段,把上一阶段的最后日期作为下一阶段的起始点,同时累积所有日期:
# 迭代生成各阶段序列并合并 result <- Reduce( function(acc, params) { # 生成当前阶段的日期序列 current_seq <- seq.Date(from = acc$next_start, to = params$to, by = params$by) # 返回累积的日期向量和下一阶段的起始日期 list( all_dates = c(acc$all_dates, current_seq), next_start = tail(current_seq, 1) ) }, phase_params, init = list(all_dates = NULL, next_start = initial_start) ) # 提取最终合并后的日期向量 all_dates <- result$all_dates
步骤3:批量处理优化
如果要处理大量患者,可将逻辑封装成函数,传入每个患者的初始日期和阶段参数即可:
generate_surgery_dates <- function(initial_start, phase_params) { result <- Reduce( function(acc, params) { current_seq <- seq.Date(from = acc$next_start, to = params$to, by = params$by) list( all_dates = c(acc$all_dates, current_seq), next_start = tail(current_seq, 1) ) }, phase_params, init = list(all_dates = NULL, next_start = initial_start) ) return(result$all_dates) } # 示例:为另一位患者生成手术日期 patient2_dates <- generate_surgery_dates( initial_start = as.Date("1968-03-15"), phase_params = list( list(by = "7 days", to = as.Date("1968-06-30")), list(by = "2 months", to = as.Date("1970-12-31")), list(by = "1 year", to = as.Date("1973-07-31")) ) )
data.table 实现方案
若偏好data.table,可结合循环计算阶段起始点,再用rbindlist合并序列,适合批量处理多患者数据:
library(data.table) # 定义单个患者的阶段参数 patient_phases <- data.table( phase_id = 1:3, by = c("10 days", "3 months", "1 year"), to = as.Date(c("1967-05-31", "1968-12-31", "1972-08-31")) ) # 初始化第一阶段的起始日期 patient_phases[phase_id == 1, start := as.Date("1967-02-01")] # 计算后续阶段的起始日期(从上一阶段最后日期开始) for (i in 2:nrow(patient_phases)) { prev_seq <- seq.Date( from = patient_phases$start[i-1], to = patient_phases$to[i-1], by = patient_phases$by[i-1] ) patient_phases[i, start := tail(prev_seq, 1)] } # 生成所有阶段的日期序列并合并 all_dates <- rbindlist( patient_phases[, .(date = seq.Date(start, to, by)), by = phase_id] )$date
内容的提问来源于stack exchange,提问作者Farrel
相关产品推荐
相关产品推荐

