如何基于多列复杂条件合并R语言中的两个dataframe?
基于多条件匹配合并数据集df1和df2的最优实现
首先明确原始数据集定义:
df1 = data.frame("String" = c("a", "b", "c"), "Title" = c("A", "B", "C"), "Date" = c("2020-01-01", "2020-01-02", "2020-01-03")) df2 = data.frame("String" = c("a", "x", "y"), "Title" = c("ABCDEF", "XYZ", "YZ"), "Date" = c("2020-01-03", "2020-01-20", "2020-01-30"))
警告原因分析
你遇到的两个警告本质是因为未处理逐行配对的逻辑:
longer object length is not a multiple of shorter object length:直接用向量级比较时,R会循环回收短向量,导致长度不匹配,且逻辑上不是在检查每一对df1/df2行的组合。argument 'pattern' has length > 1 and only the first element will be used:grepl()默认只接受单个匹配模式,传入向量时仅会使用第一个元素,无法实现逐行的子串匹配。
最优实现方式
方法1:使用tidyverse(dplyr)
通过交叉连接生成所有行组合,再过滤符合条件的记录,逻辑清晰且代码简洁:
library(dplyr) df3 <- df1 %>% # 生成df1与df2的所有行组合,自动重命名重复列 crossing(df2, .name_repair = ~c(names(df1), paste0(names(df2), "_df2"))) %>% # 过滤三个匹配条件 filter( String == String_df2, grepl(Title, Title_df2), Date < Date_df2 )
方法2:使用Base R
通过expand.grid生成交叉组合,再用mapply处理逐行的grepl匹配:
# 生成所有行组合并重命名重复列 cross_combinations <- expand.grid(df1, df2, stringsAsFactors = FALSE) names(cross_combinations) <- c(names(df1), paste0(names(df2), "_df2")) # 过滤符合条件的行 df3 <- cross_combinations[ cross_combinations$String == cross_combinations$String_df2 & mapply(grepl, pattern = cross_combinations$Title, x = cross_combinations$Title_df2) & cross_combinations$Date < cross_combinations$Date_df2, ]
最终结果
两种方法得到的df3一致:
> df3 String Title Date String_df2 Title_df2 Date_df2 1 a A 2020-01-01 a ABCDEF 2020-01-03
内容的提问来源于stack exchange,提问作者user17661126
相关产品推荐
相关产品推荐

