R语言如何基于12个月时间范围条件合并两个dataframe
R语言非等值时间范围合并解决方案
核心思路:先将两个数据框的日期列转为标准Date类型,再使用支持非等值条件的连接函数匹配符合「df2日期晚于df1日期且间隔不超过12个月」的行,最后保留df1的原始日期列即可。
方案1:tidyverse方案(dplyr 1.1.0及以上版本适用,和常用的inner_join语法兼容)
# 加载依赖包 library(dplyr) library(lubridate) # 构造示例数据 df1 <- data.frame(date = c("2020-01-01", "2018-01-01"), A = c("5", NA), B = c("4", "0")) df2 <- data.frame(date = c("2020-05-16", "2018-09-23", "2017-02-02"), C = c("2", "3", "4"), D = c("9", "10", "11")) # 转换为标准日期格式 df1$date <- as.Date(df1$date) df2$date <- as.Date(df2$date) # 非等值连接 df_result <- inner_join( df1, df2, # 定义连接条件:df2的日期晚于df1的日期,且间隔不超过12个月 join_by(date < date, y$date <= x$date + years(1)) ) %>% # 保留df1的原始日期,删除df2的日期列 select(date = x$date, A, B, C, D)
如果使用的dplyr版本低于1.1.0,可使用fuzzyjoin包实现:
library(fuzzyjoin) library(lubridate) df1$date <- as.Date(df1$date) df2$date <- as.Date(df2$date) df_result <- fuzzy_inner_join( df1, df2, by = "date", match_fun = list(function(x,y) y > x & y <= x + years(1)) ) %>% select(date = date.x, A, B, C, D)
方案2:data.table方案(适合大数据量,性能更高)
library(data.table) library(lubridate) # 转换为data.table格式并修改日期类型 setDT(df1)[, date := as.Date(date)] setDT(df2)[, date := as.Date(date)] # 非等值连接筛选 df_result <- df2[df1, .(date = i.date, A, B, C, D), on = .(date > date, date <= date + years(1)), nomatch = NULL # 仅保留匹配成功的行,等价于inner_join ]
两种方案输出结果均和需求一致。
内容的提问来源于stack exchange,提问作者MLE
相关产品推荐
相关产品推荐

