在R中计算数据集日期集合差异并生成missing列
在R中判断日期范围完整性并标记缺失
核心思路
先为每个ID生成first_date到last_date的完整日期序列,再与第二个数据框中该ID的实际日期对比,检查是否存在缺失,最后将结果合并回第一个数据框。
示例数据
先构造两组测试数据,方便你验证代码:
df1 <- data.frame( ID = c("A", "B", "C"), first_date = as.Date(c("2023-01-01", "2023-02-01", "2023-03-01")), last_date = as.Date(c("2023-01-03", "2023-02-03", "2023-03-03")) ) df2 <- data.frame( ID = c("A", "A", "A", "B", "B", "C", "C", "C"), dates = as.Date(c("2023-01-01", "2023-01-02", "2023-01-03", "2023-02-01", "2023-02-03", "2023-03-01", "2023-03-02", "2023-03-03")) )
方法一:使用tidyverse工具链
这是最常用的简洁实现方式,需要加载tidyverse包:
library(tidyverse) result <- df1 %>% # 为每个ID生成完整日期序列 mutate(full_dates = map2(first_date, last_date, ~seq(.x, .y, by = "day"))) %>% # 将日期序列拆分为单独行 unnest(full_dates) %>% # 左连接df2,匹配对应ID和日期 left_join(df2, by = c("ID", "full_dates" = "dates")) %>% # 按ID分组,检查是否存在未匹配的日期(即dates列有NA) group_by(ID) %>% summarise(missing = as.integer(any(is.na(dates)))) %>% # 合并回原始df1,保留所有ID right_join(df1, by = "ID") %>% # 调整列顺序 select(ID, first_date, last_date, missing)
代码说明:
map2配合seq:为每个ID生成从first_date到last_date的每日序列unnest:把列表格式的日期序列拆成多行,方便后续匹配- 左连接后,df2中不存在的日期会在
dates列显示为NA any(is.na(dates)):判断该ID是否存在缺失日期,转成整数1(缺失)或0(完整)
方法二:Base R实现
如果不想加载额外包,可以用基础R函数完成:
# 将df2按ID拆分,得到每个ID对应的日期列表 df2_id_dates <- split(df2$dates, df2$ID) # 遍历df1每一行,检查日期完整性 df1$missing <- sapply(1:nrow(df1), function(row_idx) { current_id <- df1$ID[row_idx] start_date <- df1$first_date[row_idx] end_date <- df1$last_date[row_idx] # 生成当前ID的完整日期序列 full_date_seq <- seq(start_date, end_date, by = "day") # 检查所有日期是否都在df2的对应ID中,取反后转成1/0 as.integer(!all(full_date_seq %in% df2_id_dates[[current_id]])) })
代码说明:
split:把df2按ID分组,每个组存储该ID的所有日期sapply:逐个处理df1的ID,生成完整日期序列后用%in%匹配检查!all(...):如果所有日期都存在则返回FALSE(转成0),有缺失则返回TRUE(转成1)
内容的提问来源于stack exchange,提问作者learner
相关产品推荐
相关产品推荐

