R语言中带条件合并df1与df2的技术实现问询
带条件合并R数据框的实现方法
首先先还原你的原始数据构造代码和生成的数据框:
原始数据构造代码
varA=c('2018-01-03', '2018-01-25','2018-01-15','2018-01-06') varB=c('2018-01-02', '2018-01-05', '2018-01-13', '2018-01-21', '2018-01-26') varC=c(201801,201802,201804,201809,201815) df1=as.data.frame(varA) df2=as.data.frame(cbind(varB,varC))
生成的数据框
df1
| 行号 | varA |
|---|---|
| 1 | 2018-01-03 |
| 2 | 2018-01-25 |
| 3 | 2018-01-15 |
| 4 | 2018-01-06 |
df2
| 行号 | varB | varC |
|---|---|---|
| 1 | 2018-01-02 | 201801 |
| 2 | 2018-01-05 | 201802 |
| 3 | 2018-01-13 | 201804 |
| 4 | 2018-01-21 | 201809 |
| 5 | 2018-01-26 | 201815 |
接下来针对带条件合并的需求,我会给出几种常见场景的实现方法,你可以根据实际条件调整:
场景1:匹配varA与varB日期最接近的记录
如果你的条件是为df1的每个日期找到df2中最接近的日期对应的varC,可以用dplyr结合fuzzyjoin包实现:
首先安装并加载所需包:
install.packages(c("dplyr", "fuzzyjoin", "lubridate")) library(dplyr) library(fuzzyjoin) library(lubridate)
先把日期列转换为日期格式(原始数据是字符型,必须转成日期才能计算):
df1 <- df1 %>% mutate(varA = ymd(varA)) df2 <- df2 %>% mutate(varB = ymd(varB), varC = as.numeric(varC))
然后进行模糊匹配,找到每个varA对应的最近varB记录:
df_closest <- df1 %>% fuzzy_left_join(df2, by = c("varA" = "varB"), match_fun = list(`>=`)) %>% group_by(varA) %>% filter(varB == max(varB)) %>% ungroup() %>% select(varA, varB, varC)
这个代码的逻辑是:先匹配所有varB小于等于varA的记录,然后在每个varA组里取最大的varB(也就是最近的前一个日期),最终得到合并结果。
场景2:基于日期范围的合并
如果你的条件是varA落在某个由varB定义的区间内(比如varB是起始日期,下一个varB是结束日期),可以这样处理:
先给df2添加结束日期列:
df2 <- df2 %>% arrange(varB) %>% mutate(varB_end = lead(varB, default = ymd("2018-12-31")))
然后用fuzzy_join匹配varA在varB和varB_end之间的记录:
df_range <- fuzzy_left_join( df1, df2, by = c("varA" = "varB", "varA" = "varB_end"), match_fun = list(`>=`, `<`) ) %>% select(varA, varB, varC)
场景3:精确匹配(如果有共同匹配键)
如果你的条件是存在精确匹配的键(比如假设varA和varB有完全相同的日期),可以用基础R的merge函数或者dplyr的left_join:
用基础R的merge
# 先转日期格式 df1$varA <- as.Date(df1$varA) df2$varB <- as.Date(df2$varB) df_exact <- merge(df1, df2, by.x = "varA", by.y = "varB", all.x = TRUE)
用dplyr的left_join
library(dplyr) df_exact <- df1 %>% mutate(varA = as.Date(varA)) %>% left_join(df2 %>% mutate(varB = as.Date(varB)), by = c("varA" = "varB"))
需要注意的是,原始数据中的日期是字符类型,必须先转换为日期格式才能进行日期相关的条件匹配,否则会按字符排序逻辑处理,结果会出错。
内容的提问来源于stack exchange,提问作者MLPNPC
相关产品推荐
相关产品推荐

