解决方案取决于您匹配 a
到 b
所需的基数。如果是一对一,则会得到上面三个最接近的匹配项。如果是多对一,则会得到六个。
一对一情况(需要分配算法):
在我之前遇到这种情况时,我将其视为一种分配问题,使用距离矩阵和分配启发式算法(下文使用贪心分配)。如果您想要一个“最优”解决方案,最好使用 optim
。
不熟悉 AGREP,但以下是使用 stringdist
的示例距离矩阵。
library(stringdist)
d <- expand.grid(a$name,b$name)
names(d) <- c("a_name","b_name")
d$dist <- stringdist(d$a_name,d$b_name, method="jw")
greedyAssign <- function(a,b,d){
x <- numeric(length(a))
while(any(x==0)){
min_d <- min(d[x==0])
a_sel <- a[d==min_d & x==0][1]
b_sel <- b[d==min_d & a == a_sel & x==0][1]
x[a==a_sel & b == b_sel] <- 1
x[x==0 & (a==a_sel|b==b_sel)] <- -1
}
cbind(a=a[x==1],b=b[x==1],d=d[x==1])
}
data.frame(greedyAssign(as.character(d$a_name),as.character(d$b_name),d$dist))
生成赋值语句:
a b d
1 Ace Co Ace Co. 0.04762
2 Bayes Bayes Inc. 0.16667
3 asd asdf 0.08333
我相信有更加优雅的方法来实现贪心分配启发式算法,但是上述方法对我来说已经足够。
多对一情况(不是一个分配问题):
do.call(rbind, unname(by(d, d$a_name, function(x) x[x$dist == min(x$dist),])))
产生结果:
a_name b_name dist
1 Ace Co Ace Co. 0.04762
11 Baes Bayes Inc. 0.20000
8 Bayes Bayes Inc. 0.16667
12 Bays Bayes Inc. 0.20000
10 Bcy Bayes Inc. 0.37778
15 asd asdf 0.08333
编辑: 使用method="jw"
可以产生所需的结果。请参阅help("stringdist-package")