用最频繁的模糊匹配替换字符串
Replace string with most frequent fuzzy match
我有一个非结构化名称的数据框,我想在一列中创建一个 'master' 已清理名称列表,在另一列中创建所有变体。我正在使用 stringdist
包。下面是一个小例子:
library(dplyr) # for pipes
library(tidyr) # for expand_grid()
library(stringdist)
words <- c("dog","dot","don","con","cry","croak","cat","dogg", "dogy", "dog", "cat", "dog")
# compare everything to everything
words_df <- expand_grid(raw = words, clean = words) %>%
mutate(dist = stringdist(raw, clean, method = "jw") %>%
# compute word frequency
group_by(clean) %>%
mutate(count = n()) %>%
filter(dist < 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"出现的频率更高。
这是我目前尝试过的方法:
dict <- words_df %>%
mutate(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
管道语句将 return 一个包含 9 行的数据框,每行对应原始 words
向量中的每个唯一元素。首先我们 group_by
raw
列为每个唯一的词创建一个组,然后 filter
通过你的距离阈值,然后在 clean
中找到频率最高的对应词原始数据集。在您的示例中,除了 "dog."
的两个变体之外,所有单词都与自己匹配
代码
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
我有一个非结构化名称的数据框,我想在一列中创建一个 'master' 已清理名称列表,在另一列中创建所有变体。我正在使用 stringdist
包。下面是一个小例子:
library(dplyr) # for pipes
library(tidyr) # for expand_grid()
library(stringdist)
words <- c("dog","dot","don","con","cry","croak","cat","dogg", "dogy", "dog", "cat", "dog")
# compare everything to everything
words_df <- expand_grid(raw = words, clean = words) %>%
mutate(dist = stringdist(raw, clean, method = "jw") %>%
# compute word frequency
group_by(clean) %>%
mutate(count = n()) %>%
filter(dist < 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"出现的频率更高。
这是我目前尝试过的方法:
dict <- words_df %>%
mutate(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
管道语句将 return 一个包含 9 行的数据框,每行对应原始 words
向量中的每个唯一元素。首先我们 group_by
raw
列为每个唯一的词创建一个组,然后 filter
通过你的距离阈值,然后在 clean
中找到频率最高的对应词原始数据集。在您的示例中,除了 "dog."
代码
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