R语言:将时间区间拆分为多行月度子区间
拆分跨月时间区间为月度子区间并保留所有字段
示例输入数据
先给出用tibble和lubridate生成的示例数据集:
library(tibble) library(lubridate) sample_data <- tibble( ID = c(1, 2), Gender = c("M", "F"), Age = c(30, 25), Time_Period = c( interval(ymd("2023-02-15"), ymd("2023-05-20")), interval(ymd("2023-07-01"), ymd("2023-08-10")) ) )
解决方案代码
用tidyverse工具链实现拆分,不管原数据集有多少列,都能完整保留所有字段:
library(tidyverse) # 定义拆分单个时间区间为月度子区间的函数 split_interval_to_months <- function(int) { start_date <- int_start(int) end_date <- int_end(int) # 生成所有覆盖月份的第一天 month_starts <- seq(floor_date(start_date, "month"), floor_date(end_date, "month"), by = "month") # 逐个生成月度子区间:第一个从原区间起始日开始,最后一个到原区间结束日 map(month_starts, function(ms) { sub_start <- max(ms, start_date) sub_end <- min(ceiling_date(ms, "month") - days(1), end_date) interval(sub_start, sub_end) }) } # 应用拆分并展开数据 result <- sample_data %>% mutate(Time_Period = map(Time_Period, split_interval_to_months)) %>% unnest(Time_Period)
输出结果
运行后得到的拆分结果如下:
result #> # A tibble: 5 × 4 #> ID Gender Age Time_Period #> <dbl> <chr> <dbl> <Interval> #> 1 1 M 30 2023-02-15 UTC--2023-02-28 UTC #> 2 1 M 30 2023-03-01 UTC--2023-03-31 UTC #> 3 1 M 30 2023-04-01 UTC--2023-04-30 UTC #> 4 1 M 30 2023-05-01 UTC--2023-05-20 UTC #> 5 2 F 25 2023-07-01 UTC--2023-08-10 UTC
关键说明
- 自定义函数
split_interval_to_months专门处理单个interval类型数据,自动适配起始/结束日期不是月初/月末的情况 map函数对每行的时间区间进行批量拆分,生成列表列unnest将列表列展开为多行,原数据的所有其他列(比如ID、Gender、Age等)都会自动保留,就算实际数据集列数再多也能兼容
内容的提问来源于stack exchange,提问作者Scott White
相关产品推荐
相关产品推荐

