如何高效拆分跨月日期数据以实现按月统计汇总
R语言跨月时间区间拆分方案
适用场景
需要按自然月统计周期时长时,拆分跨多个月份的长周期记录为对应单个月份的分段记录。
依赖包
需要提前安装加载以下常用数据处理包:
install.packages(c("dplyr", "lubridate", "tidyr")) library(dplyr) library(lubridate) library(tidyr)
完整实现代码
# 构造原始示例数据,同时将日期列转换为Date格式 data <- data.frame( start_date = c("2020-01-02", "2020-08-21","2020-09-01"), end_date = c("2020-03-01", "2020-09-07", "2020-09-30"), ID = c("A", "B", "C") ) %>% mutate(across(c(start_date, end_date), ymd)) # 核心拆分逻辑 result <- data %>% rowwise() %>% # 生成当前记录覆盖的所有月份的第一天列表 mutate(month = list(seq( from = floor_date(start_date, unit = "month"), to = floor_date(end_date, unit = "month"), by = "month" ))) %>% unnest(month) %>% # 计算每个单月分段的起止日期 mutate( seg_start = if_else(month == floor_date(start_date, "month"), start_date, month), seg_end = if_else(month == floor_date(end_date, "month"), end_date, ceiling_date(month, "month") - days(1)) ) %>% # 整理输出字段 select(start_date = seg_start, end_date = seg_end, ID) %>% ungroup()
输出结果验证
运行后得到的result数据如下,和预期结果一致(注:预期结果中2020-03-01-的末尾横杠为输入笔误,2020年为闰年2月实际有29天,若需要按非闰年统计可自行调整逻辑):
> result # A tibble: 6 × 3 start_date end_date ID <date> <date> <chr> 1 2020-01-02 2020-01-31 A 2 2020-02-01 2020-02-29 A 3 2020-03-01 2020-03-01 A 4 2020-08-21 2020-08-31 B 5 2020-09-01 2020-09-07 B 6 2020-09-01 2020-09-30 C
内容的提问来源于stack exchange,提问作者Sang won kim
相关产品推荐
相关产品推荐

