R语言是否存在支持模糊字符串检测的包或现成函数?
R语言自定义容错度的模糊字符串匹配方案
需求说明
需要找到和stringr::str_detect()逻辑一致(检测长字符串中是否包含目标关键词)、支持自定义模糊匹配容错度(可指定允许1个/2个字符的插入、删除、替换等差异)的工具,无需针对单个场景定制正则规则,适配带随机录入噪声的文本分类场景。
示例中原有精确匹配代码无法识别带轻微字符偏差的关键词,导致分类结果出现NA,期望能正确识别所有存在小偏差的关键词,输出正确分类。
实现方案
采用通用编辑距离匹配逻辑实现,可自由调整容错阈值,不需要针对特定错误编写定制规则:
- 核心规则:默认将1次字符插入、删除、替换算作1个差异,符合常规人工录入错误的匹配判定习惯。
- 可运行代码如下:
library(tidyverse) # 自定义模糊分类函数 fuzzy_detect_category <- function(text_vec, keyword_map, max_tolerance = 2, ignore_case = FALSE) { # keyword_map为两列数据框:category存分类名,keyword存对应匹配关键词 all_cats <- unique(keyword_map$category) map_chr(text_vec, function(single_text) { res <- NA_character_ for (cat in all_cats) { cat_keywords <- keyword_map$keyword[keyword_map$category == cat] # 检测当前文本是否模糊命中分类下任意关键词 is_hit <- any( map_lgl(cat_keywords, function(kw) { agrepl( pattern = kw, x = single_text, max.distance = list( insertions = max_tolerance, deletions = max_tolerance, substitutions = max_tolerance ), ignore.case = ignore_case ) }) ) if (is_hit) { res <- cat break } } res }) } # 测试数据 my_restaurants <- tibble(restaurant = c("MCDOlNALD'S ON FRANKLIN ST", "NEW JERSEY WENDYS", "8/25/19 RUTH CHRIS", "MELTINGPOT 9823i3") ) # 关键词分类库 keyword_lib <- tribble( ~category, ~keyword, "CHEAP", "MCDONALD'S", "CHEAP", "WENDY'S", "EXPENSIVE", "RUTH CHRIS", "EXPENSIVE", "MELTING POT" ) # 执行匹配 my_restaurants %>% mutate(category = fuzzy_detect_category(restaurant, keyword_lib, max_tolerance = 2))
参数调整说明
- 调整
max_tolerance参数即可修改容错等级:设为1时最多允许1个字符差异,设为2时最多允许2个字符差异,可根据自身数据的噪声程度灵活调整。 - 若需要忽略大小写差异,将函数参数
ignore_case设为TRUE即可。 - 若需要将相邻字符打反(如把"CHRIS"打成"CHIRS")算作1个差异,可将底层匹配逻辑替换为
stringdist包的Damerau-Levenshtein距离计算,适配更多录入错误场景,不需要修改上层分类逻辑。
运行上述代码即可得到期望的输出结果:
# A tibble: 4 × 2 restaurant category <chr> <chr> 1 MCDOlNALD'S ON FRANKLIN ST CHEAP 2 NEW JERSEY WENDYS CHEAP 3 8/25/19 RUTH CHRIS EXPENSIVE 4 MELTINGPOT 9823i3 EXPENSIVE
该方案所有模糊规则通用,数据量较大时也能保持稳定的匹配效率,维护成本远低于针对单个错误编写的定制正则。
内容的提问来源于stack exchange,提问作者justing
相关产品推荐
相关产品推荐

