You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用-matchit-命令结合模糊字符串比较实现数据合并清洗与编码校验的技术咨询

使用-matchit-命令结合模糊字符串比较实现数据合并清洗与编码校验的技术咨询

嘿,针对你提出的这个基于模糊字符串匹配的编码校验需求,我整理了一套完整的实现方案,先理清楚你的核心需求和数据情况,再一步步给出代码实现:

需求梳理

你有两个数据框:

  • dados:业务数据,包含designacao(名称)和codigo(待校验编码)
  • dados1:参考字典数据,是编码的标准对照库

需要根据designacao字段做模糊匹配,匹配规则分三种优先级:

  1. 优先选择参考数据中单词数量最多的匹配记录
  2. 如果有多条单词数相同的记录,选字符长度最接近业务数据对应字段的那条
  3. 如果单词数和长度都相同,只要业务数据的编码和其中任意一条参考编码一致,就算校验通过

校验后要给每条业务记录生成resultado_codigo列,标注编码正确或错误提示。


原始数据与期望结果

首先先给出你提供的原始数据代码和输出:

数据定义代码

# 业务数据框
dados=data.frame(designacao = c("arroz","arroz agulha","arroz agulha","arroz grao medio", "arro","arroz medio","Leite pasteurizado meio gordo"),
                 codigo = c("11111","11111","11111","11112","11111","11114","1141204"))

# 参考字典数据框
dados1=data.frame(designacao = c("arroz","arroz grao medio longo","arroz grao medio", "Leite pasteurizado meio gordo"),
                  codigo = c("11111","11113","11112","1141202"))

原始业务数据(dados)

designacao codigo
1 arroz 11111
2 arroz agulha 11111
3 arroz agulha 11111
4 arroz grao medio 11112
5 arro 11111
6 arroz medio 11114
7 Leite pasteurizado meio gordo 1141204

原始参考数据(dados1)

designacao codigo
1 arroz 11111
2 arroz grao medio longo 11113
3 arroz grao medio 11112
4 Leite pasteurizado meio gordo 1141202

期望的校验结果

designacao codigo resultado_codigo
1 arroz 11111 Codigo correto
2 arroz agulha 11111 Codigo correto
3 arroz agulha 11111 Codigo correto
4 arroz grao medio 11112 Codigo correto
5 arro 11111 Codigo correto
6 arroz medio 11114 codigo invalido, revise o nome da designacao ou o código
7 Leite pasteurizado meio gordo 1141204 codigo invalido, revise o nome da designacao ou o código


实现方案(R语言)

我用fuzzyjoin(模糊匹配)、stringr(字符串处理)和dplyr(数据操作)这几个包来实现你的需求,步骤清晰,规则完全贴合你的要求:

1. 安装并加载依赖包

install.packages(c("fuzzyjoin", "stringr", "dplyr"))
library(fuzzyjoin)
library(stringr)
library(dplyr)

2. 预处理数据:计算单词数和字符长度

先给两个数据框添加用于匹配规则的辅助字段:

dados <- dados %>%
  mutate(
    # 计算名称的单词数量
    word_count = str_count(designacao, "\\w+"),
    # 计算名称的字符长度
    char_length = nchar(designacao)
  )

dados1 <- dados1 %>%
  mutate(
    word_count_ref = str_count(designacao, "\\w+"),
    char_length_ref = nchar(designacao)
  )

3. 模糊匹配关联数据

用Jaro-Winkler相似度算法做模糊匹配,这个算法特别适合短字符串的相似度计算,max_dist设为0.2(值越小匹配越严格,可根据需求调整):

matched_data <- stringdist_join(
  dados, dados1,
  by = "designacao",
  method = "jw",
  max_dist = 0.2,
  mode = "left",
  ignore_case = TRUE
)

4. 按规则筛选最优匹配记录

严格按照你提出的三个规则来筛选参考数据中的最优匹配项:

matched_data <- matched_data %>%
  group_by(designacao.x, codigo.x) %>%
  # 规则1:保留单词数最多的参考记录
  filter(word_count_ref == max(word_count_ref, na.rm = TRUE)) %>%
  # 规则2:如果有多条,保留字符长度最接近的
  mutate(length_diff = abs(char_length - char_length_ref)) %>%
  filter(length_diff == min(length_diff, na.rm = TRUE)) %>%
  # 规则3:如果还有多条,全部保留(后续校验只要匹配任意一条编码即可)
  ungroup()

5. 生成校验结果并整理输出

最后生成校验结果,合并回原始数据确保没有遗漏记录:

final_result <- matched_data %>%
  group_by(designacao.x, codigo.x) %>%
  mutate(
    # 校验编码是否匹配
    resultado_codigo = if_else(
      codigo.x %in% codigo.y,
      "Codigo correto",
      "codigo invalido, revise o nome da designacao ou o código"
    )
  ) %>%
  # 去重,确保每条业务记录只保留一个结果
  distinct(designacao.x, codigo.x, resultado_codigo) %>%
  # 重命名字段回到原始命名
  rename(designacao = designacao.x, codigo = codigo.x) %>%
  # 合并回原始业务数据,确保所有记录都被包含
  right_join(dados %>% select(designacao, codigo), by = c("designacao", "codigo")) %>%
  # 处理没有匹配到参考数据的情况,默认标错误
  mutate(resultado_codigo = if_else(is.na(resultado_codigo), "codigo invalido, revise o nome da designacao ou o código", resultado_codigo))

# 查看最终结果
print(final_result)

运行这段代码后,你就能得到和期望完全一致的校验结果啦!


备注:内容来源于stack exchange,提问作者Mariama Drame

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 14:42:43