适用于R的一对多实现

时间:2014-02-27 17:49:40

标签: r foreach apply

我必须比较字符串并检查它们是否匹配。我的样本数据如下所示。

m6
PLOT#39 H#8-2-293/A4/A/
PLOT #39 H #8-2-293/A4/A
PLOT NO 1030 BUNGLOW NO
PLOT NO 1030 BUNGLOW NO
PLOT 1030 BUNGLOW NO 3
PLOT NO-39 H#8-2-293/A4/
GAYATRAI RESIDENCY MADHU 

我将第一个字符串的每个单词与第二个字符串中的所有单词进行比较。像这样我最终写了4个循环。执行需要很长时间。我在考虑应用函数,但我不确定如何在这种情况下使用它们。因此,任何改进代码的想法都将非常有用。感谢

    m <- strapply(m6, "(\\S+)", c)      
    for(i in 1:(length(m)-1)){      
        for(n in (i+1):(length(m))){            
            for(j in 1:length(m[[i]])){
                for(k in 1:length(m[[n]])){
                    if(length(agrep(m[[i]][j], m[[n]][k], ignore.case = TRUE))!= 0){
                        ....
                    }
                }
            }
        }
    }

2 个答案:

答案 0 :(得分:3)

您可以使用函数adist计算字符串之间的Levenshtein距离。

e.g。 :

v <- c('aaa','aab','adb','aaa','bb')
distances <- adist(v)
row.names(distances) <- v
colnames(distances) <- v

> distances
    aaa aab adb aaa bb
aaa   0   1   2   0  3
aab   1   0   1   1  2
adb   2   1   0   2  2
aaa   0   1   2   0  3
bb    3   2   2   3  0

解释结果:

  • distances["adb","aaa"] = 2,因为字符串"adb"需要进行两次修改才能成为"aaa"'d''b'替换为'a')。
  • distances["bb","aaa"] = 3,因为字符串"bb"需要进行三次修改才能成为"aaa"(两个'b'替换为'a',另一个'a'添加)。

答案 1 :(得分:0)

使用agrep的实现:

near.idx <- apply(     # Find matches
  combn(m6, 2), 2,     # compare all string combinations
  function(x) as.logical(length(agrep(x[[1]], x[[2]], 5L)))
)
apply(                 # Display matches
  combn(seq_along(m6), 2)[, near.idx], 2, 
  function(x) paste0(m6[x[[1]]], " **MATCHES** ", m6[x[[2]]])
)

产生:

[1] "PLOT#39 H#8-2-293/A4/A/ **MATCHES** PLOT #39 H #8-2-293/A4/A" 
[2] "PLOT #39 H #8-2-293/A4/A **MATCHES** PLOT NO-39 H#8-2-293/A4/"
[3] "PLOT NO 1030 BUNGLOW NO **MATCHES** PLOT NO 1030 BUNGLOW NO"  
[4] "PLOT NO 1030 BUNGLOW NO **MATCHES** PLOT 1030 BUNGLOW NO 3"   
[5] "PLOT NO 1030 BUNGLOW NO **MATCHES** PLOT 1030 BUNGLOW NO 3"  

agrep会对两个字符串进行近似匹配。您可以调整尝试与max.distance和其他参数匹配的积极程度。另外,在这里我只是选择打印出来的东西,但是你可以存储匹配,或者从原始向量中删除匹配,无论如何。