You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按组ID计算带协变量的时间区间并集与交集?

按组计算时间区间的交集与并集并保留协变量

针对按患者(id)分组计算干预时段(A)和药物治疗时段(B)的交集、并集,同时保留对应协变量的需求,以下是基于data.table的高效实现方案,可支持大规模数据集:

一、准备工作:统一数据结构(添加分组id)

先给示例数据补充分组id,模拟真实场景下的多患者结构:

library(data.table)

# 补充id字段,模拟单患者场景(实际多患者只需扩展id值即可)
A <- data.table(
  id = 1,
  start = as.Date(c("2022-10-16", "2023-06-16")),
  stop  = as.Date(c("2023-03-12", "2023-10-12")),
  covar_A = c("P-int 1", "P-int 2")
)

B <- data.table(
  id = 1,
  start = as.Date(c("2022-10-16", "2023-08-16")),
  stop  = as.Date(c("2023-01-12", "2023-12-12")),
  covar_B = c("Drug 1", "Drug 2")
)

二、计算区间交集(A ∩ B)

利用foverlaps()匹配重叠区间,直接计算交集时段并保留协变量:

# 设置data.table的键,用于区间匹配
setkey(A, id, start, stop)
setkey(B, id, start, stop)

# 执行区间重叠匹配
overlaps <- foverlaps(A, B, type = "any", nomatch = NULL)

# 计算交集的起止时间:取两个区间的晚开始、早结束
overlaps[, `:=`(
  intersect_start = pmax(start, i.start),
  intersect_stop = pmin(stop, i.stop)
)]

# 筛选有效交集(开始时间 < 结束时间),整理结果
intersection <- overlaps[intersect_start < intersect_stop, .(
  id,
  开始时间 = intersect_start,
  结束时间 = intersect_stop,
  covar_A = covar_A,
  covar_B = covar_B
)]

# 查看结果
print(intersection)

分组处理时data.table会自动按id并行处理,效率极高,最终输出与预期交集结果一致。

三、计算区间并集(A ∪ B)

并集需要先拆分所有时间节点,生成连续区间后匹配对应协变量:

# 收集所有id下的时间节点(A和B的start、stop)
time_points <- rbind(
  A[, .(id, time = start)],
  A[, .(id, time = stop)],
  B[, .(id, time = start)],
  B[, .(id, time = stop)]
)

# 按id和时间排序,去重
time_points <- time_points[order(id, time)][!duplicated(.SD), .SD, .SDcols = c("id", "time")]

# 生成连续区间:每个节点作为下一个区间的开始
time_points[, `:=`(
  开始时间 = time,
  结束时间 = shift(time, type = "lead")
), by = id]

# 移除最后一行(无结束时间的节点)
union_intervals <- time_points[!is.na(结束时间), .(id, 开始时间, 结束时间)]

# 匹配A的协变量:找到区间所属的A时段
setkey(A, id, start, stop)
setkey(union_intervals, id, 开始时间, 结束时间)
union_intervals <- foverlaps(union_intervals, A, type = "within", nomatch = NA)[, .(
  id, 开始时间, 结束时间, covar_A = i.covar_A
)]

# 匹配B的协变量:找到区间所属的B时段
setkey(B, id, start, stop)
setkey(union_intervals, id, 开始时间, 结束时间)
union_intervals <- foverlaps(union_intervals, B, type = "within", nomatch = NA)[, .(
  id, 开始时间, 结束时间, covar_A, covar_B = i.covar_B
)]

# 按时间排序结果
union_intervals <- union_intervals[order(id, 开始时间)]

# 查看结果
print(union_intervals)

这段代码会生成预期的并集输出,空白时段(无A/B覆盖)的协变量会自动填充为NA。

四、扩展到多患者场景

上述代码天然支持多患者:只需在A和B数据中包含不同的id值,data.table的分组操作(by = id)会自动处理每个患者的区间,无需额外修改。对于数千患者、数万个区间的数据集,data.table的内存操作和分组优化能保证高效运行。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 03:43:14