如何在R语言中按列唯一值将时间区间数据拆分为年月
R语言提取接收器活跃年月的实现方法
先模拟一份和你需求匹配的输入数据,方便演示:
library(tidyverse) library(lubridate) # 模拟输入数据集 receivers <- tibble( Receiver = c("R001", "R002", "R003"), start_dt = ymd(c("2022-03-15", "2023-01-01", "2021-11-20")), end_dt = ymd(c("2022-05-20", "2023-03-10", "2022-01-05")) )
核心实现方案(Tidyverse 风格)
用map2生成每个接收器的活跃月份序列,再通过unnest展开成每行对应一个年月的格式:
receivers_active_months <- receivers %>% # 将起止日期对齐到当月第一天,生成完整的月份序列 mutate(active_months = map2(start_dt, end_dt, ~seq(floor_date(.x, "month"), floor_date(.y, "month"), by = "month"))) %>% # 把列表列展开为多行 unnest(active_months) %>% # 转换为YYYY-MM格式的年月字符串 mutate(active_year_month = format(active_months, "%Y-%m")) %>% # 保留需要的字段 select(Receiver, active_year_month)
运行后输出结果如下:
print(receivers_active_months) #> # A tibble: 9 × 2 #> Receiver active_year_month #> <chr> <chr> #> 1 R001 2022-03 #> 2 R001 2022-04 #> 3 R001 2022-05 #> 4 R002 2023-01 #> 5 R002 2023-02 #> 6 R002 2023-03 #> 7 R003 2021-11 #> 8 R003 2021-12 #> 9 R003 2022-01
关键步骤说明
floor_date(..., "month"):不管接收器是当月哪天启动/停止,都把日期对齐到当月第一天,确保整个月份被计入活跃列表map2:遍历每一行的起止日期,生成连续的月份序列unnest:把每个接收器对应的多个年月从列表中展开,变成一行对应一个活跃年月的结构
备选:Base R 实现
如果不习惯用Tidyverse,也可以用基础R代码完成:
# Base R 版本 active_months_list <- lapply(1:nrow(receivers), function(i) { # 对齐起止日期到当月第一天 start_month <- floor_date(receivers$start_dt[i], "month") end_month <- floor_date(receivers$end_dt[i], "month") # 生成月份序列 months_seq <- seq(start_month, end_month, by = "month") # 构造结果数据框 data.frame( Receiver = receivers$Receiver[i], active_year_month = format(months_seq, "%Y-%m") ) }) # 合并所有结果 receivers_active_months_base <- do.call(rbind, active_months_list)
内容的提问来源于stack exchange,提问作者fishlakeslimno
相关产品推荐
相关产品推荐

