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

如何用R的stringdist和dplyr实现药品名称最优字符串匹配?

解决方案

要实现每个原始药品名称匹配最优官方名称的需求,你需要按原始名称分组后筛选出距离最小的行(stringdist的距离值越小,字符串相似度越高),而非简单用固定阈值过滤。以下是具体实现:

library(stringdist)
library(dplyr)

# 计算字符串距离,按原始名称分组筛选最优匹配
result <- df %>%
  # 计算Jaro-Winkler距离,值越小表示字符串越相似
  mutate(name_dist = stringdist(orig_names, desired_names, method = "jw")) %>%
  # 按原始药品名称分组
  group_by(orig_names) %>%
  # 筛选每组中距离最小的行(若存在多个相同最小距离的匹配,可加slice_head(n=1)指定保留第一个)
  filter(name_dist == min(name_dist)) %>%
  # 移除临时计算的距离列(可选)
  select(-name_dist) %>%
  ungroup()

# 查看结果
result

运行后会得到预期的desired_df:

# A tibble: 2 × 3
  orig_names desired_names desired_names_code
  <chr>      <chr>                      <dbl>
1 KOGENATE   KOGENATE FS                   1
2 ADVATE     ADVATE                        3

关键说明

  • 距离逻辑:stringdist的jw方法返回0-1的距离值,0代表完全匹配,1代表完全不匹配。因此要找最优匹配,需筛选最小距离的行,而非大于某个阈值。
  • 分组筛选:通过group_by(orig_names)确保每个原始名称只保留一个最优匹配结果,避免无差别过滤导致的错误。
  • 平局处理:如果同一原始名称存在多个相同最小距离的匹配项,可通过slice_head(n=1)/slice_tail(n=1)或业务规则(如编码大小)进一步指定保留项。

原代码无效的原因

你之前的代码逻辑存在两个核心问题:

  • 条件stringdist(...) > 0.5会保留相似度极低的行,和找最优匹配的需求完全相反;
  • 未按原始名称分组,无法保证每个原始名称仅保留一个最优结果。

内容的提问来源于stack exchange,提问作者TheGoat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 00:57:29