R语言使用like运算符实现多匹配项数据框合并与扫描
R语言多公司获奖年份匹配实现方案
现有数据结构
待处理的两个数据框代码如下:
df1 <- data.frame (Year = c(1991, 1992, 1993, 1994, 1995, 1996, 1997), Winner = c("APPLE ", "apple inc.", "APPLE INC.; IBM CO.", "SONATA", "FAMILY BROS", "family, apple, ibm","family co.") ) df2 <- data.frame (Firm = c("APPLE ", "IBM", "Sonata Inc.","Family Bros. Co."))
目标是生成新数据框,匹配每家公司对应的所有获奖年份,支持单一年份对应多个获奖主体的场景,目标输出格式参考示例:
可直接复用的实现方法
核心逻辑是先做字符串标准化清洗,再做大小写不敏感的模糊匹配,不需要提前拆分多主体的获奖字段,两种常用实现路径如下:
方法1:tidyverse方案(代码易读,适合日常分析)
依赖dplyr和stringr包,步骤清晰易调整:
library(tidyverse) # 预处理公司名称:去首尾空格、统一转小写、移除通用后缀避免匹配偏差 df2_clean <- df2 %>% mutate( firm_trim = str_trim(Firm), firm_low = str_to_lower(firm_trim), firm_core = str_remove_all(firm_low, "\\s*(inc\\.?|co\\.?|bros\\.?)\\s*$") ) # 逐公司匹配获奖年份 df3 <- df2_clean %>% mutate( match_year = map(firm_core, ~{ df1 %>% filter(str_detect(str_to_lower(Winner), fixed(.x))) %>% pull(Year) }) ) %>% unnest(match_year) %>% select(Firm, Year = match_year)
运行后可以直接得到长表格式的结果,1993年Apple+IBM同时获奖、1996年family+apple+ibm同时获奖的场景都会被正确识别,不会遗漏多主体的匹配记录。如果需要把同一家公司的所有年份合并到同一单元格,只需要把最后一步的unnest替换为mutate(match_year = map_chr(match_year, ~paste(.x, collapse = "、")))即可。
方法2:data.table方案(性能优异,适合大数据量场景)
如果数据量在十万级以上,用data.table的模糊连接效率比tidyverse高5~10倍:
library(data.table) setDT(df1) setDT(df2) # 统一做字符串清洗 df2[, firm_core := tolower(gsub("\\s*(inc\\.?|co\\.?|bros\\.?)\\s*$", "", trimws(Firm)))] df1[, winner_low := tolower(Winner)] # 模糊连接匹配 df3 <- df1[, .(Year, winner_low)][ df2[, .(Firm, firm_core)], on = .(winner_low = firm_core), allow.cartesian = T, j = .(Firm, Year), # 自定义匹配规则:获奖字段包含公司核心关键词即判定命中 on = .(grepl(firm_core, winner_low, fixed = T)) ][!is.na(Firm)]
匹配优化提示
- 清洗字符串时除了统一大小写、去空格、删通用后缀,还可以根据实际数据补充替换规则,比如把"int'l"替换为"international"这类缩写,进一步提升匹配准确率
- 如果存在同名不同主体的情况,可以额外给公司加所属行业、国家等辅助字段做二次校验,避免错配
内容的提问来源于stack exchange,提问作者PhD Student
相关产品推荐
相关产品推荐

