R 用最频繁的模糊匹配替换字符串

R 用最频繁的模糊匹配替换字符串,r,stringdist,R,Stringdist,我有一个非结构化名称的数据框架,我想在一列中创建一个已清理名称的“主”列表,在另一列中创建所有变体。我正在使用stringdist包。下面是一个小例子: library(dplyr)#用于管道 图书馆(tidyr)#用于扩展网格() 图书馆(stringdist) 字% #计算词频 分组依据(清洁)%>% 突变(计数=n())%>% 过滤器(距离% 过滤器(距离% 汇总(clean=clean[which.max(count)]) 输出 #一个tible:9 x 2 生洁 一只猫 2 con

我有一个非结构化名称的数据框架,我想在一列中创建一个已清理名称的“主”列表,在另一列中创建所有变体。我正在使用
stringdist
包。下面是一个小例子:

library(dplyr)#用于管道
图书馆(tidyr)#用于扩展网格()
图书馆(stringdist)
字%
#计算词频
分组依据(清洁)%>%
突变(计数=n())%>%
过滤器(距离<0.3)
这将导致所有足够相似组合的距离和字数的df:

|raw |clean |      dist| count|
|:---|:-----|---------:|-----:|
|dog |dog   | 0.0000000|    36|
|dog |dot   | 0.2222222|    12|
|dog |don   | 0.2222222|    12|
|dog |dogg  | 0.0833333|    12|
|dog |dogy  | 0.0833333|    12|
|dog |dog   | 0.0000000|    36|
|dog |dog   | 0.0000000|    36|
|dot |dog   | 0.2222222|    36|
|dot |dot   | 0.0000000|    12|
|dot |don   | 0.2222222|    12|

您可以看到,在
clean
列中,我有两个“dog”和“dogg”条目,我希望将它们折叠成一个条目(dog),因为字符串“dog”出现得更频繁

以下是我到目前为止所做的尝试:

dict%
变异(clean_new=ifelse(dist<0.085,words_df[which.max(words_df$count)][1][1],clean))
其结果是:

|raw |clean |      dist| count|clean_new |
|:---|:-----|---------:|-----:|:---------|
|dog |dog   | 0.0000000|    36|NA        |
|dog |dot   | 0.2222222|    12|dot       |
|dog |don   | 0.2222222|    12|don       |
|dog |con   | 0.4444444|    12|con       |
|dog |cry   | 1.0000000|    12|cry       |
|dog |croak | 0.4888889|    12|croak     |
|dog |cat   | 1.0000000|    24|cat       |
|dog |dogg  | 0.0833333|    12|NA        |
|dog |dogy  | 0.0833333|    12|NA        |
|dog |dog   | 0.0000000|    36|NA        |

基本上,我想要创建的是一个包含单词所有变体的字典,基于最接近单词匹配的频率


谢谢大家

dplyr
pipe语句将返回一个包含9行的数据帧,其中一行对应原始
words
向量中的每个唯一元素。首先,我们通过
raw
列对u进行分组,该列为每个唯一的单词创建一个组,然后通过距离阈值对
进行过滤,然后在
clean
中找到原始数据集中频率最高的对应单词。在您的示例中,除了“dog”的两个变体之外,所有单词都匹配

代码
words\u df%>%
分组依据(原始)%>%
过滤器(距离<0.085)%>%
汇总(clean=clean[which.max(count)])
输出
#一个tible:9 x 2
生洁
一只猫
2 con con
3呱呱
哭喊
5只狗
6只狗
7小狗
8堂堂
9点

只是为了将来指出,如果您将代码扩展到一个很长的单词列表,那么该代码将非常低效。如果有许多重复,它将冗余地计算相同单词对的距离分数。更有效的解决方案是计算
unique(words)
上的成对距离,将每个单词的计数分别制成表格,然后将两者结合起来。
words_df %>%
  group_by(raw) %>%
  filter(dist < 0.085) %>%
  summarize(clean = clean[which.max(count)])
# A tibble: 9 x 2
  raw   clean
  <chr> <chr>
1 cat   cat  
2 con   con  
3 croak croak
4 cry   cry  
5 dog   dog  
6 dogg  dog  
7 dogy  dog  
8 don   don  
9 dot   dot