如何按分组起止日期补全DataFrame中的缺失日期区间?
问题描述
现有如下DataFrame df:
> df group date1 date2 value 1 A 2023-01-04 2023-01-06 1 2 A 2023-01-06 2023-01-07 2 3 A 2023-01-08 2023-01-09 3 4 B 2023-01-05 2023-01-06 3 5 B 2023-01-06 2023-01-08 2 6 B 2023-01-08 2023-01-10 1
需要补全2023-01-01至2023-01-10之间的缺失日期区间,按group分组处理。以分组A为例,缺失的区间包括:2023-01-01至2023-01-04、2023-01-07至2023-01-08、2023-01-09至2023-01-10,这些缺失区间的value填充为NA,最终期望输出如下:
group date1 date2 value 1 A 2023-01-01 2023-01-04 NA 2 A 2023-01-04 2023-01-06 1 3 A 2023-01-06 2023-01-07 2 4 A 2023-01-07 2023-01-08 NA 5 A 2023-01-08 2023-01-09 3 6 A 2023-01-09 2023-01-10 NA 7 B 2023-01-01 2023-01-05 NA 8 B 2023-01-05 2023-01-06 3 9 B 2023-01-06 2023-01-08 2 10 B 2023-01-08 2023-01-10 1
数据定义:
df <- data.frame( group = rep(c("A", "B"), each = 3L), date1 = c( "2023-01-04", "2023-01-06", "2023-01-08", "2023-01-05", "2023-01-06", "2023-01-08" ), date2 = c( "2023-01-06", "2023-01-07", "2023-01-09", "2023-01-06", "2023-01-08", "2023-01-10" ), value = c(1, 2, 3, 3, 2, 1) )
解决方案
可以通过dplyr分组处理,结合tidyr和lubridate工具生成完整日期序列并构建区间,步骤如下:
library(dplyr) library(tidyr) library(lubridate) # 1. 将字符串日期转换为日期类型 df <- df %>% mutate(across(c(date1, date2), ymd)) # 2. 按分组生成完整日期区间并匹配原始数据 result <- df %>% group_by(group) %>% # 收集所有关键日期:全局起止日期 + 原始数据的date1/date2 summarise(dates = c(ymd("2023-01-01"), date1, date2, ymd("2023-01-10")), .groups = "drop") %>% # 按分组和日期排序,去除重复日期 group_by(group) %>% arrange(dates) %>% distinct(dates) %>% # 将连续日期两两组合成区间:当前日期为date1,下一个日期为date2 mutate(date1 = dates, date2 = lead(dates)) %>% # 移除最后一行(无对应date2的无效行) filter(!is.na(date2)) %>% # 左连接原始数据,自动填充缺失区间的value为NA left_join(df, by = c("group", "date1", "date2")) %>% arrange(group, date1) # 查看最终结果 print(result)
核心逻辑
- 先统一日期格式,避免字符串处理的误差
- 收集所有需要覆盖的日期节点,确保不遗漏全局起止点和原始数据的区间端点
- 将连续节点转换为完整区间,再通过左连接匹配原始数据的有效
value,缺失区间自动填充NA
内容的提问来源于stack exchange,提问作者Quinten
相关产品推荐
相关产品推荐

