我有一些名字,想要获取其中唯一的名字。但是由于拼写错误和数据不一致,这些名字可能被错误地书写。我正在寻找一种方法,在一个字符串向量中检查两个字符串是否相似。
例如:
pres <- c(" Obama, B.","Bush, G.W.","Obama, B.H.","Clinton, W.J.")
我想找出" Obama, B."
和"Obama, B.H."
非常相似。有没有办法做到这一点?
可以根据Levenshtein距离等方法来完成。不同的程序包中实现了多种解决方案和程序包。这些问题的答案中可以找到一些解决方案和程序包:
但通常使用agrep
就可以满足您的需求:
> sapply(pres,agrep,pres)
$` Obama, B.`
[1] 1 3
$`Bush, G.W.`
[1] 2
$`Obama, B.H.`
[1] 1 3
$`Clinton, W.J.`
[1] 4
也许你需要使用 agrep
?它可以使用Levenshtein编辑距离搜索近似匹配。
lapply(pres, agrep, pres, value = TRUE)
[[1]]
[1] " Obama, B." "Obama, B.H."
[[2]]
[1] "Bush, G.W."
[[3]]
[1] " Obama, B." "Obama, B.H."
[[4]]
[1] "Clinton, W.J."
添加另一个副本以展示它可以处理多个副本。
pres <- c(" Obama, B.","Bush, G.W.","Obama, B.H.","Clinton, W.J.", "Bush, G.")
adist 显示两个字符向量之间的字符串距离
adist(" Obama, B.", pres)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 9 3 10 7
" Obama, B."
最接近的字符串,可以选择距离最小的那个。为了避免选择相同的字符串,我只选取大于零的距离值:
d <- adist(" Obama, B.", pres)
pres[min(d[d>0])]
# [1] "Obama, B.H."
keepunique()
的函数来执行此操作。keepunique()
随后使用Reduce()
依次应用于向量的所有元素。keepunique <- function(previousones, x){
if(any(adist(x, previousones)<5)){
x <- NULL
}
return(c(previousones, x))
}
Reduce(keepunique, pres)
# [1] " Obama, B." "Bush, G.W." "Clinton, W.J."