R语言如何高效计算每个日历年对应的总随访时长
高效计算日历年总随访时长的R实现
核心思路
无需生成逐天的随访日期序列,直接对每条随访记录拆分到覆盖的所有年份,单独计算每条记录在对应年份的随访天数,最后按年份汇总即可,全程向量化运算无显式循环。
依赖包
需要提前安装加载dplyr、lubridate、tidyr三个R数据处理常用工具包。
实现代码
# 原始数据 df <- data.frame( id = c("A", "B"), start = as.Date(c("2015-01-01", "2013-01-01")), end = as.Date(c("2021-06-12", "2017-10-10")) ) library(dplyr) library(lubridate) library(tidyr) result <- df %>% # 生成每条随访记录覆盖的所有年份序列 mutate(year = purrr::map2(year(start), year(end), ~seq(.x, .y))) %>% # 拆分年份,每条记录拆分为对应年份的多条子记录 unnest(year) %>% mutate( # 计算当前年份的起止边界 year_start = ymd(paste0(year, "-01-01")), year_end = ymd(paste0(year, "-12-31")), # 取随访实际在当年的起止日期 actual_start = pmax(start, year_start), actual_end = pmin(end, year_end), # 计算当年随访天数,+1是因为起止日期当天都计入随访 follow_days = as.integer(actual_end - actual_start) + 1 ) %>% # 按年份汇总总随访年数 group_by(year) %>% summarise(follow_years = sum(follow_days) / 365)
结果验证
输出的result和原有方案的计算结果完全一致:
| year | follow_years |
|---|---|
| 2013 | 1.0000000 |
| 2014 | 1.0000000 |
| 2015 | 2.0000000 |
| 2016 | 2.0054795 |
| 2017 | 1.7753425 |
| 2018 | 1.0000000 |
| 2019 | 1.0000000 |
| 2020 | 1.0027397 |
| 2021 | 0.4465753 |
性能说明
该方案避免了逐天生成日期的内存开销和循环操作,处理10万条以上的随访记录也能在秒级完成,远优于原有循环逐天统计的方案。如果需要更严谨的闰年修正,只需要把汇总步骤的分母替换为ifelse(leap_year(year), 366, 365)即可。
内容的提问来源于stack exchange,提问作者ECII
相关产品推荐
相关产品推荐

