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

多日期范围DataFrame关联匹配:按日期匹配Anzahl列

问题:按日期范围匹配关联DataFrame的数值列

现有liste DataFrame结构如下:

> liste
       Datum Verfahren Fachgebiet Praxis Rang
1 2025-04-09         0          0      0   17
2 2025-04-09         0          0      0   56
3 2025-07-12         0          0      0  200
4 2025-04-14         0          0      0    7
5 2025-04-14         0          0      0  167
6 2025-04-14         0          1      0  208

需根据liste每行的Datum日期,匹配对应日期范围的kombinationen DataFrame中的Anzahl值。这些kombinationen结构一致,仅Anzahl值随日期范围变化。

当前多次执行merge的代码会导致列重复(如Anzahl.x、Anzahl.y)且丢失部分行,不符合预期。预期结果是每行根据Datum匹配对应日期范围的Anzahl:

> liste
       Datum Verfahren Fachgebiet Praxis Rang Anzahl
1 2025-04-09         0          0      0   17    231
2 2025-04-09         0          0      0   56    231
3 2025-07-12         0          0      0  200    233  <- changed value
4 2025-04-14         0          0      0    7    231
5 2025-04-14         0          0      0  167    231
6 2025-04-14         0          1      0  208    188

错误原因分析

原循环代码存在以下问题:

  • 每次merge都会生成新的Anzahl列,导致列重复堆积
  • 使用subset(liste, Datum <= i[[1]])会过滤掉当前日期范围外的行,最终丢失部分原始数据
  • 循环中不断覆盖liste,导致数据被错误叠加

解决方案

方法1:基础R实现

步骤:

  1. 将所有日期对应的kombinationen整合为带日期标记的完整数据集
  2. 为liste每行找到最大的不超过该行Datum的关联日期
  3. 根据匹配的日期和关联列(Verfahren、Fachgebiet、Praxis)合并Anzahl值

代码实现:

# 1. 构造完整的日期关联数据集
kombinationen_full <- do.call(rbind, lapply(anzahl, function(x) {
  df <- kombinationen
  df$Anzahl <- x[[2]]
  df$Geltungsdatum <- as.Date(x[[1]])
  df
}))

# 2. 转换liste的Datum为日期类型
liste$Datum <- as.Date(liste$Datum)

# 3. 为每行匹配对应生效日期
liste$matched_date <- mapply(function(d) {
  max(kombinationen_full$Geltungsdatum[kombinationen_full$Geltungsdatum <= d])
}, liste$Datum)

# 4. 合并数据并整理列
result <- merge(liste, kombinationen_full, 
                by.x = c("Verfahren", "Fachgebiet", "Praxis", "matched_date"),
                by.y = c("Verfahren", "Fachgebiet", "Praxis", "Geltungsdatum"),
                all.x = TRUE)
result <- result[, c("Datum", "Verfahren", "Fachgebiet", "Praxis", "Rang", "Anzahl")]

方法2:dplyr + lubridate实现(更简洁)

library(dplyr)
library(lubridate)

# 构造完整的日期关联数据集
kombinationen_full <- bind_rows(lapply(anzahl, function(x) {
  kombinationen %>%
    mutate(Anzahl = x[[2]],
           Geltungsdatum = ymd(x[[1]]))
}))

# 匹配并合并数据
result <- liste %>%
  mutate(Datum = ymd(Datum)) %>%
  rowwise() %>%
  mutate(matched_date = max(kombinationen_full$Geltungsdatum[kombinationen_full$Geltungsdatum <= Datum])) %>%
  ungroup() %>%
  left_join(kombinationen_full, 
            by = c("Verfahren", "Fachgebiet", "Praxis", "matched_date" = "Geltungsdatum")) %>%
  select(Datum, Verfahren, Fachgebiet, Praxis, Rang, Anzahl)

验证结果

运行上述代码后,得到的result即为预期格式:

> result
       Datum Verfahren Fachgebiet Praxis Rang Anzahl
1 2025-04-09         0          0      0   17    231
2 2025-04-09         0          0      0   56    231
3 2025-07-12         0          0      0  200    233
4 2025-04-14         0          0      0    7    231
5 2025-04-14         0          0      0  167    231
6 2025-04-14         0          1      0  208    188

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 16:58:11