细微差别的模糊匹配
Fuzzy matching for slight difference
我有一列公司名称,我想计算该列中有多少家不同的公司。在这个栏目中,一些相同的公司名称略有不同,例如,这些公司应该只计算一次。
ASAHI INTECC CO., LTD.
Asahi Intecc USA Inc
ASAHI INTECC USA, INC
我想要通用的代码,可以精确统计公司的数量,而不是重复计算有细微差异的公司。
例如,此可重现数据应 return 值为 6
company <- read.table(text = "
CompanyName
'MERCK SHARP & DOHME CORPORATION'
'GILEAD SCIENCES INC'
'BOEHRINGER INGELHEIM PHARMACEUTICALS, INC.'
'ABBVIE, INC.'
'JANSSEN SCIENTIFIC AFFAIRS, LLC'
'BOEHRINGER INGELHEIM PHARMA GMBH & CO.KG'
'ASAHI INTECC CO., LTD.'
'Asahi Intecc USA Inc'
", header = TRUE, stringsAsFactors = FALSE)
我看了
How can I match fuzzy match strings from two datasets?
但我仍然不知道如何构建代码。希望大家多多指教
要比较字符串之间的相似性,第一步通常是使用您所掌握的最佳知识清理数据:
由于很多计算字符串距离的方法会将大小写字母视为不同的字母,所以首先要将所有字符转换为相同的大小写。您可以进行任何其他清洁以帮助提高准确性。
library(dplyr)
companyName <- company$CompanyName %>%
toupper() %>% # convert to upper case
stringr::str_replace_all("\s+"," ") %>% # convert any consecutive whitespaces to single space
stringr::str_remove_all("\.|,") # remove all comma or dot
> companyName
[1] "MERCK SHARP & DOHME CORPORATION" "GILEAD SCIENCES INC" "BOEHRINGER INGELHEIM PHARMACEUTICALS INC"
[4] "ABBVIE INC" "JANSSEN SCIENTIFIC AFFAIRS LLC" "BOEHRINGER INGELHEIM PHARMA GMBH & COKG"
[7] "ASAHI INTECC CO LTD" "ASAHI INTECC USA INC"
计算字符串距离:
distanceMatrix <- stringdist::stringdistmatrix(
a = companyName,
b = companyName,
# You can pick the method that works best for your data. Also, manual inspection is needed. See ?stringdist
# I'm picking soundex for this example
method = "soundex"
)
使用soundex
方法,如果一个单元格是0
,则表示对应的行和列非常接近
> distanceMatrix
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 0 1 1 1 1 1 1 1
[2,] 1 0 1 1 1 1 1 1
[3,] 1 1 0 1 1 0 1 1
[4,] 1 1 1 0 1 1 1 1
[5,] 1 1 1 1 0 1 1 1
[6,] 1 1 0 1 1 0 1 1
[7,] 1 1 1 1 1 1 0 0
[8,] 1 1 1 1 1 1 0 0
这意味着,在companyName
向量中,第3项接近第6项,第7项接近第8项。
result <- which(distanceMatrix==0,arr.ind = TRUE) %>%
as.data.frame() %>%
dplyr::filter(col > row)
> result
row col
1 3 6
2 7 8
> result %>% mutate_all(~companyName[.x])
row col
1 BOEHRINGER INGELHEIM PHARMACEUTICALS INC BOEHRINGER INGELHEIM PHARMA GMBH & COKG
2 ASAHI INTECC CO LTD ASAHI INTECC USA INC
请注意,在计算字符串距离时,您可以通过清理字符串或选择不同的方法、参数或阈值来提高准确性。但它永远无法保证 100% 的准确性。
最后,要统计独特的公司,我们可以这样做:
> length(companyName) - length(unique(result$row))
[1] 6
我有一列公司名称,我想计算该列中有多少家不同的公司。在这个栏目中,一些相同的公司名称略有不同,例如,这些公司应该只计算一次。
ASAHI INTECC CO., LTD.
Asahi Intecc USA Inc
ASAHI INTECC USA, INC
我想要通用的代码,可以精确统计公司的数量,而不是重复计算有细微差异的公司。 例如,此可重现数据应 return 值为 6
company <- read.table(text = "
CompanyName
'MERCK SHARP & DOHME CORPORATION'
'GILEAD SCIENCES INC'
'BOEHRINGER INGELHEIM PHARMACEUTICALS, INC.'
'ABBVIE, INC.'
'JANSSEN SCIENTIFIC AFFAIRS, LLC'
'BOEHRINGER INGELHEIM PHARMA GMBH & CO.KG'
'ASAHI INTECC CO., LTD.'
'Asahi Intecc USA Inc'
", header = TRUE, stringsAsFactors = FALSE)
我看了 How can I match fuzzy match strings from two datasets? 但我仍然不知道如何构建代码。希望大家多多指教
要比较字符串之间的相似性,第一步通常是使用您所掌握的最佳知识清理数据:
由于很多计算字符串距离的方法会将大小写字母视为不同的字母,所以首先要将所有字符转换为相同的大小写。您可以进行任何其他清洁以帮助提高准确性。
library(dplyr)
companyName <- company$CompanyName %>%
toupper() %>% # convert to upper case
stringr::str_replace_all("\s+"," ") %>% # convert any consecutive whitespaces to single space
stringr::str_remove_all("\.|,") # remove all comma or dot
> companyName
[1] "MERCK SHARP & DOHME CORPORATION" "GILEAD SCIENCES INC" "BOEHRINGER INGELHEIM PHARMACEUTICALS INC"
[4] "ABBVIE INC" "JANSSEN SCIENTIFIC AFFAIRS LLC" "BOEHRINGER INGELHEIM PHARMA GMBH & COKG"
[7] "ASAHI INTECC CO LTD" "ASAHI INTECC USA INC"
计算字符串距离:
distanceMatrix <- stringdist::stringdistmatrix(
a = companyName,
b = companyName,
# You can pick the method that works best for your data. Also, manual inspection is needed. See ?stringdist
# I'm picking soundex for this example
method = "soundex"
)
使用soundex
方法,如果一个单元格是0
,则表示对应的行和列非常接近
> distanceMatrix
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 0 1 1 1 1 1 1 1
[2,] 1 0 1 1 1 1 1 1
[3,] 1 1 0 1 1 0 1 1
[4,] 1 1 1 0 1 1 1 1
[5,] 1 1 1 1 0 1 1 1
[6,] 1 1 0 1 1 0 1 1
[7,] 1 1 1 1 1 1 0 0
[8,] 1 1 1 1 1 1 0 0
这意味着,在companyName
向量中,第3项接近第6项,第7项接近第8项。
result <- which(distanceMatrix==0,arr.ind = TRUE) %>%
as.data.frame() %>%
dplyr::filter(col > row)
> result
row col
1 3 6
2 7 8
> result %>% mutate_all(~companyName[.x])
row col
1 BOEHRINGER INGELHEIM PHARMACEUTICALS INC BOEHRINGER INGELHEIM PHARMA GMBH & COKG
2 ASAHI INTECC CO LTD ASAHI INTECC USA INC
请注意,在计算字符串距离时,您可以通过清理字符串或选择不同的方法、参数或阈值来提高准确性。但它永远无法保证 100% 的准确性。
最后,要统计独特的公司,我们可以这样做:
> length(companyName) - length(unique(result$row))
[1] 6