You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:34:53