如何用R计算职业暴露时长?重叠年份仅统计一次
解决R语言中职业暴露重叠时长去重计算问题
核心思路
针对每个研究对象-暴露因子组合,先合并重叠/相邻的暴露时段,再计算合并后所有时段的总时长(重叠年份仅统计一次)。
示例数据构造
先模拟你提到的dat数据集:
dat <- data.frame( ID = c(1, 2, 2), Exposure = c("A", "A", "A"), YEARIN = c(1990, 1995, 1998), YEAROUT = c(2000, 2000, 2005) )
其中研究对象2的两个职业时段1995-2000和1998-2005存在3年重叠,最终总时长应为11年(1995-2005共11年)。
方法1:使用IRanges包(高效处理大型数据集)
IRanges是专门用于区间操作的工具包,适合你的大型数据库:
# 安装包(首次使用需执行) install.packages("IRanges") library(IRanges) library(dplyr) # 计算去重后的总暴露时长 result <- dat %>% group_by(ID, Exposure) %>% summarise( # 创建闭区间对象(包含起始和结束年份) ranges = IRanges(start = YEARIN, end = YEAROUT), # 合并重叠/相邻区间 merged_ranges = reduce(ranges), # 计算总时长:每个区间时长为结束年-起始年+1,再求和 total_duration = sum(end(merged_ranges) - start(merged_ranges) + 1), .groups = "drop" )
运行后result会输出每个ID-暴露因子组合的去重总时长。
方法2:纯dplyr实现(无额外依赖)
如果不想安装额外包,可以用dplyr手动合并区间:
library(dplyr) # 计算去重后的总暴露时长 result <- dat %>% group_by(ID, Exposure) %>% arrange(YEARIN) %>% # 按起始年份排序,保证区间顺序正确 mutate( # 标记独立区间:当前时段起始年 > 上一个时段结束年+1时,视为新区间 interval_group = cumsum(YEARIN > lag(YEAROUT, default = -Inf) + 1) ) %>% group_by(ID, Exposure, interval_group) %>% summarise( start_year = min(YEARIN), end_year = max(YEAROUT), .groups = "drop" ) %>% group_by(ID, Exposure) %>% summarise( total_duration = sum(end_year - start_year + 1), .groups = "drop" )
此方法逻辑清晰,无需额外依赖,适合小型到中型数据集。
结果验证
针对示例数据,两种方法都会得到:
| ID | Exposure | total_duration |
|---|---|---|
| 1 | A | 11 |
| 2 | A | 11 |
符合预期(研究对象2的重叠年份已去重)。
内容的提问来源于stack exchange,提问作者R_help
相关产品推荐
相关产品推荐

