R语言日期范围匹配:返回查找表首个匹配行对应值
R按ID关联日期区间并提取目标字段实现方案
匹配规则说明
- 关联前提:
df1与df2的Id字段完全一致 - 区间判断:
df1的Date落在df2对应Id下的[Date.Start, Date.End]闭区间内 - 取值逻辑:取
df2中首个满足匹配条件行的Return.Value,无匹配返回空值NA
方法1:Base R 原生实现(无需安装第三方包)
逻辑直观易调试,适合小数据量场景:
# 初始化Return.Value列为空值 df1$Return.Value <- NA_real_ # 逐行遍历df1完成匹配 for (i in seq_len(nrow(df1))) { curr_id <- df1$Id[i] curr_date <- df1$Date[i] # 查找df2中同ID且日期区间命中的行号 match_idx <- which( df2$Id == curr_id & df2$Date.Start <= curr_date & curr_date <= df2$Date.End ) # 存在匹配则取第一个命中项的Return.Value if (length(match_idx) > 0) { df1$Return.Value[i] <- df2$Return.Value[match_idx[1]] } }
方法2:fuzzyjoin 模糊连接实现(大数据量性能更优)
避免逐行循环,适合万行以上的数据集,需加载第三方包:
# 首次使用请先安装依赖 # install.packages(c("dplyr", "fuzzyjoin")) library(dplyr) library(fuzzyjoin) df1 <- df1 %>% # 左连接:Id精确匹配,日期做区间模糊匹配 fuzzy_left_join( df2, by = c("Id" = "Id", "Date" = "Date.Start", "Date" = "Date.End"), match_fun = list(`==`, `>=`, `<=`) ) %>% # 按df1原始行分组,仅保留每组第一个匹配结果 group_by(Date, Id.x) %>% slice(1) %>% ungroup() %>% # 清理冗余字段,保持和原df1结构一致 select(Date, Id = Id.x, Return.Value)
结果验证
运行上述代码后输出结果完全匹配示例要求:
- df1第一行(Id=4,日期2021-08-09)命中df2第3行区间,返回
Return.Value=3- df1第二行(Id=6,日期2021-08-09)无对应命中区间,返回
NA- 其余行均按df2的行顺序取首个匹配值,无跨ID匹配错误
内容的提问来源于stack exchange,提问作者MKa
相关产品推荐
相关产品推荐

