在R语言中按日期区间匹配合并数据框并填充分类字段
R语言:将区间数据匹配到连续日期并填充分类字段
我有两个数据框:
- df1包含三列:起始日期(date_start)、结束日期(date_end)和严重程度分类(category)
- df2包含一列连续日期(date),是2020年1月的每日日期
需要把df1的category字段填充到df2中对应的date_start至date_end区间内,得到匹配后的结果。
示例数据
df1 <- data.frame(matrix(ncol = 3, nrow = 2)) colnames(df1)[1:3] <- c('date_start','date_end','category') df1$date_start <- c(as.Date('2020-01-02'), as.Date('2020-01-10')) df1$date_end <- c(as.Date('2020-01-05'), as.Date('2020-01-13')) df1$category <- c('moderate','strong') df2 <- data.frame(matrix(ncol = 1, nrow = 15)) colnames(df2)[1] <- 'date' df2$date <- seq.Date(as.Date('2020-01-01'), as.Date('2020-01-15'), 1)
理想结果
date category 1 2020-01-01 NA 2 2020-01-02 moderate 3 2020-01-03 moderate 4 2020-01-04 moderate 5 2020-01-05 moderate 6 2020-01-06 NA 7 2020-01-07 NA 8 2020-01-08 NA 9 2020-01-09 NA 10 2020-01-10 strong 11 2020-01-11 strong 12 2020-01-12 strong 13 2020-01-13 strong 14 2020-01-14 NA 15 2020-01-15 NA
方法1:Base R 实现
先把df1的每个日期区间展开为每日数据,再和df2做左连接:
# 展开df1的日期区间 df1_expanded <- do.call(rbind, lapply(1:nrow(df1), function(i) { data.frame( date = seq.Date(df1$date_start[i], df1$date_end[i], by = "day"), category = df1$category[i] ) })) # 与df2左连接并排序 result <- merge(df2, df1_expanded, by = "date", all.x = TRUE) result <- result[order(result$date), ] row.names(result) <- NULL print(result)
方法2:dplyr + lubridate 实现
用tidyverse工具链更简洁,适合习惯管道操作的用户:
library(dplyr) library(lubridate) result <- df2 %>% # 先做笛卡尔积连接,再筛选符合区间的记录 left_join(df1, by = character()) %>% filter(date >= date_start & date <= date_end | is.na(date_start)) %>% select(date, category) %>% # 每个日期只保留一条记录(若有区间重叠需按需调整) group_by(date) %>% slice(1) %>% ungroup() %>% # 补全df2中所有日期,确保无遗漏 right_join(df2, by = "date") %>% arrange(date) print(result)
注:如果df1存在日期区间重叠的情况,需要根据实际需求处理多分类的情况,比如取第一个分类、合并分类等。
方法3:data.table 实现
适合处理大数据量,非等连接效率更高:
library(data.table) setDT(df1) setDT(df2) # 非等连接匹配日期区间 result <- df2[df1, on = .(date >= date_start, date <= date_end), .(date = x.date, category = i.category)] %>% unique() %>% right_join(df2, by = "date") %>% arrange(date) print(result)
内容的提问来源于stack exchange,提问作者tassones
相关产品推荐
相关产品推荐

