2012-02-02 88 views
4

我有两个分别收集的同一组学生的名字列表。有许多印刷错误,我一直使用模糊匹配来链接两个列表。我有99 +%agrep和类似的,但我坚持以下基本问题:我怎么能匹配(例如)名字“阿德里安布鲁斯”和“布鲁斯阿德里安”? Levenshtein编辑距离不适用于这种特殊情况,因为它会计算替换次数。R中的“名字姓氏”/“姓氏名字”的与顺序无关的模糊匹配?

这一定是一个非常普遍的问题,但我找不到任何标准的R软件包或例程来解决它。我想我错过了一些明显的...... ???

+0

正如@Ritchie Cotton指出的那样,你如何处理3个以上的名字,可选的姓氏连字符?你可以拆分''和' - '。在我看来,你可以通过按字母顺序重新排列名称元组来设置规范排序:cat(sort(c('Smith','John')),collapse ='')给出'John Smith'' – smci 2014-05-17 20:55:29

+0

I编辑您的标题以指定与*“名字姓氏”/“姓氏名字”*的订单独立性。如果你需要更多的通用性,请重新编辑。 – smci 2014-05-17 21:01:58

回答

3

好吧,一个很简单的方法是交换的话,再搭配......

y=c("Bruce Almighty", "Lee, Bruce", "Leroy Brown") 
y2 <- sub("(.*) (.*)", "\\2 \\1", y) 

agrep("Bruce Lee", y) # No match 
agrep("Bruce Lee", y2) # Match! 
+0

子 - 至少给我另一个新的命令。辉煌,谢谢汤米。 – 2012-02-02 20:24:27

+1

@JonathanBurley:注意非标准名称。你应该测试你的代码对c(“Lulu”,“Ho Chi Minh”,“Hugh Fearnley-Whittingstall”,NA)'。 – 2012-02-03 11:19:36

+0

@JonathanBurley:'grep,grepl,regexpr,gregexpr,regexec,sub,gsub'和'match/pmatch'(查看相关:'charmatch')实质上都是相同的底层命令。喜欢R语言!感觉像新一代的PHP! – smci 2014-05-17 20:59:02

0

我通常使用的是相当强劲和相对不敏感的排序,标点等方面的技术。它是基于称为“n-grams”的对象。如果n = 2,则为“bigrams”。例如:

"Adrian Bruce" --> ("Ad","dr","ri","ia","an","n "," B","Br","ru","uc","ce") 
"Bruce Adrian" --> ("Br","ru","uc","ce","e "," A","Ad","dr","ri","ia","an") 

每个字符串有11个bigrams。其中9个是共同的。因此,相似性得分非常高:9/11或0.818,其中1.000是完美匹配。

我对R不是很熟悉,但是如果一个包不存在,这种技术很容易编码。你可以编写一个循环遍历字符串1的代码,并计算出字符串2中包含了多少个字符。