【发布时间】:2011-08-27 23:56:19
【问题描述】:
我有一堆名字,我想获得唯一的名字。但是,由于数据中的拼写错误和不一致,名称可能会写错。如果其中两个相似,我正在寻找一种方法来检查字符串向量。
例如:
pres <- c(" Obama, B.","Bush, G.W.","Obama, B.H.","Clinton, W.J.")
我想发现" Obama, B." 和"Obama, B.H." 非常相似。有没有办法做到这一点?
【问题讨论】:
我有一堆名字,我想获得唯一的名字。但是,由于数据中的拼写错误和不一致,名称可能会写错。如果其中两个相似,我正在寻找一种方法来检查字符串向量。
例如:
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 显示2个字符向量之间的字符串距离
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."
【讨论】: