如何在R中对多列进行两两及多组合模糊匹配?
在R中实现多列模糊匹配的组合分析
问题说明
现有4个文本向量,需要完成以下两个任务:
- 通过模糊匹配找出所有列组合(两两、三列、四列全组合)中的共同匹配值;
- 生成一个包含原4个向量列、16行对应所有列组合(含空组合)、以及各组合共同词频的数据集。
示例数据
col1 <- c("Lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", "sed", "do") col2 <- c("Lorem", "ipsum", "Dolor", "adipiscing", "elite", "sed", "doo") col3 <- c("dolore", "adipiscing", "sed", "doo") col4 <- c("ipsun", "dolor", "sit", "amet", "consecteture", "adipiscing", "elit", "sed", "do")
系统化实现步骤
1. 文本标准化(模糊匹配前置处理)
模糊匹配前先统一文本格式,消除大小写、词根差异,避免因格式问题漏匹配:
library(tidyverse) library(stringr) library(SnowballC) # 定义标准化函数:转小写+提取词根+去空格 standardize_text <- function(text) { text %>% str_to_lower() %>% wordStem(language = "english") %>% str_trim() } # 把所有向量整理成列表并标准化 cols_list <- list(col1 = col1, col2 = col2, col3 = col3, col4 = col4) %>% map(~ standardize_text(.x))
2. 生成所有列组合
生成4个列的所有可能组合(包括空组合,共16个):
# 生成从0到4列的所有子集组合 col_combinations <- map(0:4, ~ combn(names(cols_list), .x, simplify = FALSE)) %>% flatten() # 给每个组合命名,方便后续标识 names(col_combinations) <- map_chr(col_combinations, ~ ifelse(length(.x) == 0, "空组合", paste(.x, collapse = "-")))
3. 模糊匹配找共同值并统计词频
用Jaccard相似度做模糊匹配,找出每个组合内的共同匹配项并统计出现次数:
library(stringdist) # 定义函数:针对单个组合,找出模糊匹配的共同值及词频 find_common_matches <- function(comb) { # 空组合直接返回空结果 if (length(comb) == 0) { return(tibble(common_value = character(0), frequency = integer(0))) } # 提取组合内所有去重后的文本 comb_text <- cols_list[comb] %>% map(~ unique(.x)) %>% reduce(full_join, by = character(), keep = TRUE) %>% pivot_longer(everything(), values_to = "text") %>% drop_na(text) # 计算文本间的Jaccard距离,阈值设为0.2(可调整,值越小匹配越严格) matches <- comb_text %>% group_by(text) %>% mutate(match_indices = map(text, ~ which(stringdist(.x, comb_text$text, method = "jaccard") <= 0.2))) %>% unnest(match_indices) %>% distinct(text, comb_text$text[match_indices]) %>% rename(match_value = `comb_text$text[match_indices]`) %>% filter(text != match_value) %>% group_by(text) %>% summarise(frequency = n(), .groups = "drop") %>% rename(common_value = text) return(matches) } # 批量处理所有组合,得到每个组合的匹配结果 combination_results <- map_dfr(col_combinations, find_common_matches, .id = "column_combination")
4. 生成最终数据集
将原向量数据与匹配结果合并,整理成符合需求的格式:
# 把原向量转成长格式,方便合并 original_data <- cols_list %>% bind_cols() %>% mutate(row_id = row_number()) %>% pivot_longer(-row_id, names_to = "original_column", values_to = "value") # 合并原数据与匹配结果,得到最终数据集 final_dataset <- combination_results %>% left_join(original_data, by = c("common_value" = "value")) %>% arrange(column_combination)
关键调整点
- 模糊匹配阈值:
stringdist中的jaccard距离阈值可根据需求修改,比如设为0.1会更严格,0.3会更宽松; - 文本标准化:如果不需要词根提取,可去掉
wordStem步骤; - 组合范围:如果不需要空组合,只需把
map(0:4)改成map(1:4),得到15个非空组合。
内容的提问来源于stack exchange,提问作者Thomas J. Brailey
相关产品推荐
相关产品推荐

