使用dplyr按年份拆分数据帧:基于天数分配数值
R实现按年份拆分时间区间并分配数值
给定如下R数据框:
df = data.frame(x = 1000, time_L = '2018-12-30', time_R = "2020-10-30")
我们需要按年份拆分时间区间,生成各区间的起止日期、天数,再按天数占比分配x值得到xprime,最终输出和示例一致的结果。
解决方案代码
先加载处理日期和数据所需的包:
library(lubridate) library(dplyr)
然后一步步处理数据:
# 把字符串格式的日期转成Date类型 df_processed <- df %>% mutate( time_L = ymd(time_L), time_R = ymd(time_R) ) # 提取时间跨度的起始和结束年份,生成年份序列 start_year <- year(df_processed$time_L) end_year <- year(df_processed$time_R) years <- seq(start_year, end_year, by = 1) # 为每个年份生成对应的时间区间 split_df <- lapply(years, function(y) { if (y == start_year) { # 起始年的区间从原开始日期到当年年底 period_L <- df_processed$time_L period_R <- ymd(paste(y, 12, 31, sep = "-")) } else if (y == end_year) { # 结束年的区间从当年年初到原结束日期 period_L <- ymd(paste(y, 1, 1, sep = "-")) period_R <- df_processed$time_R } else { # 中间年份取全年 period_L <- ymd(paste(y, 1, 1, sep = "-")) period_R <- ymd(paste(y, 12, 31, sep = "-")) } data.frame( time_L = period_L, time_R = period_R, x = df_processed$x ) }) %>% bind_rows() # 计算各区间天数和分配后的xprime result <- split_df %>% mutate( diff = as.numeric(time_R - time_L) + 1, # 包含首尾两天,所以加1 total_days = sum(diff), xprime = round(x * diff / total_days) ) %>% select(time_L, time_R, diff, xprime) # 输出结果 print(result)
运行后得到的结果和示例完全一致:
time_L time_R diff xprime 1 2018-12-30 2018-12-31 2 3 2 2019-01-01 2019-12-31 365 544 3 2020-01-01 2020-10-30 304 453
关键逻辑说明
- 日期转换:用
lubridate::ymd把字符串转成标准Date类型,方便年份提取和日期差计算。 - 区间拆分:根据年份是起始年、中间年还是结束年,分别设置对应的起止日期,确保每个年份的区间都准确覆盖。
- 天数计算:
time_R - time_L得到的是两个日期之间的间隔天数,但我们需要包含首尾两天,所以加1,比如2018-12-30到2018-12-31实际是2天,计算后结果正确。 - xprime计算:用每个区间的天数占总天数的比例乘以原始x值,再取整,得到分配后的数值,和示例的取整结果一致。
内容的提问来源于stack exchange,提问作者ADEN
相关产品推荐
相关产品推荐

