R语言:将DataFrame产品列匹配另一DataFrame两列并添加产品编码
高效匹配DataFrame产品名称并添加对应编码的解决方案
我有两个DataFrame:
df1(70万行):包含product列存储产品名称,还有其他20列数据df2(4万行):包含product_code、product_name、product_aka_name核心字段
需要为df1新增product_code列,匹配规则是df1$product匹配df2的product_name或product_aka_name任一即可。之前尝试过match()、grep()和fuzzyjoin,要么失败要么效率极低,需要高效方案。
核心思路
先将df2转换为产品名称-编码的映射表:把product_name和product_aka_name合并为一列,过滤无效的NA值,确保每个产品名称只对应一个编码,再通过哈希连接快速匹配到df1,这种方法的时间复杂度远低于逐行匹配,适合大数据集。
方法1:使用dplyr + tidyr(代码简洁,易读)
library(dplyr) library(tidyr) # 构建产品名称到编码的映射表 match_mapping <- df2 %>% # 将product_name和product_aka_name转为长格式,统一为product_match列 pivot_longer( cols = c(product_name, product_aka_name), names_to = NULL, values_to = "product_match" ) %>% # 过滤NA值,避免无效匹配 filter(!is.na(product_match)) %>% # 确保每个产品名称只对应一个编码(若有重复,保留第一条) distinct(product_match, .keep_all = TRUE) # 与df1左连接,添加product_code列 df1_with_code <- df1 %>% left_join(match_mapping, by = c("product" = "product_match")) %>% # 调整列顺序与期望结果一致 select(product, col2, col3, product_code) # 查看结果 print(df1_with_code)
方法2:使用data.table(性能最优,适合超大数据集)
data.table的哈希连接在处理百万级数据时速度远超基础R和dplyr,适合你的70万行df1:
library(data.table) # 转换为data.table格式 setDT(df1) setDT(df2) # 构建映射表:将product_name和product_aka_name合并,去重去NA match_mapping <- melt( df2, id.vars = "product_code", measure.vars = c("product_name", "product_aka_name"), value.name = "product_match" )[, -"variable"] %>% # 移除无用的variable列 na.omit() %>% # 过滤NA unique(by = "product_match") # 去重,确保每个名称对应唯一编码 # 左连接匹配,直接在df1中新增product_code列 df1[match_mapping, on = .(product = product_match), product_code := i.product_code] # 查看结果 print(df1)
结果验证
运行上述代码后,得到的结果与期望完全一致:
product col2 col3 product_code 1: Abcd DLK qdsf88 1002 2: Efgh CBN sdf63 1003 3: Ijkl ABC dd995 <NA> 4: Mnop ZHU dgsg1 1005 5: Qrst HSC xxx587 1004 6: Uvwx LJK dfr55 1006
注意事项
- 如果
df2中存在同一个产品名称对应多个product_code的情况,distinct()或unique()会保留第一条匹配的编码,你可以根据实际业务需求调整去重逻辑(比如保留最新/最大的编码)。 - 确保
product、product_name、product_aka_name的字符格式一致(比如大小写、空格),否则会匹配失败,必要时可以先做标准化处理(如tolower()、trimws())。
内容的提问来源于stack exchange,提问作者Bernard Forgues
相关产品推荐
相关产品推荐

