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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 17:15:39