如何计算R语言数据集中时间区间在各年份的持续时长
计算时间区间在各年份的持续时长(R语言实现)
我有一个包含id、startyr(起始日期,以年为单位的小数)、endyr(结束日期,以年为单位的小数)三个变量的R语言数据集df,需要计算每个时间区间在各整数年份的持续时长。例如区间2023.50-2024.50,需将0.5年分配给2023年,0.5年分配给2024年。
数据集生成代码
id <- rep(1:100, times = 1) startyr <- rnorm(n = 100, mean = 2024, sd = 1) endyr <- startyr + 0.325 df <- data.frame(id, startyr, endyr) # 查看前5行数据 head(df) # id startyr endyr # 1 1 2023.067 2023.392 # 2 2 2024.936 2025.261 # 3 3 2025.173 2025.498 # 4 4 2024.615 2024.940 # 5 5 2023.747 2024.072
理想输出示例
# id startyr endyr dur2023 dur2024 dur2025 dur2026 # X 2023.5 2024.5 0.5 0.5 0 0 # Y 2024.15 2026.15 0 0.85 1 0.15
实现方案
可以使用tidyverse工具包完成需求,核心思路是拆分时间区间到对应年份、计算各年份有效时长,最后转成宽格式输出:
# 加载工具包 library(tidyverse) # 计算各年份持续时长 df_dur <- df %>% # 按行处理每个数据点 rowwise() %>% # 生成该区间覆盖的所有整数年份(比如2023.7-2024.2覆盖2023、2024) mutate(year = list(floor(startyr):floor(endyr))) %>% # 把年份列表展开为多行数据 unnest(year) %>% # 计算每个年份内的有效时长 mutate( year_start = year, year_end = year + 1, # 取区间与年份的重叠部分长度 duration = pmin(endyr, year_end) - pmax(startyr, year_start) ) %>% # 转宽格式,每个年份对应一列,缺失年份填充0 pivot_wider( names_from = year, values_from = duration, names_prefix = "dur", values_fill = 0 ) # 查看处理后的前5行数据 head(df_dur)
如果需要限定输出的年份范围(比如只保留2023-2026),可以修改代码如下,确保指定年份全部显示,无重叠的年份时长为0:
df_dur_fixed <- df %>% rowwise() %>% # 指定要包含的年份范围 mutate(year = list(2023:2026)) %>% unnest(year) %>% mutate( year_start = year, year_end = year + 1, # 确保无重叠时时长为0 duration = pmax(0, pmin(endyr, year_end) - pmax(startyr, year_start)) ) %>% pivot_wider( names_from = year, values_from = duration, names_prefix = "dur", values_fill = 0 )
内容的提问来源于stack exchange,提问作者llxx2021
相关产品推荐
相关产品推荐

