【问题标题】:R Finding elements matching with each other within a vectorR在向量中查找相互匹配的元素
【发布时间】:2019-12-31 08:01:39
【问题描述】:

我有一个地址列表。这些地址是由不同的用户输入的,因此写入相同地址的方式有很多差异。例如,

"andheri at weh pump house", "andheri pump house","andheri pump house(mt)","weh andheri pump house","weh andheri pump house et","weh, nr. pump house" 

上面的向量有6个地址。而且几乎所有的都是一样的。我正在尝试找到这些地址之间的匹配项,以便我可以将它们组合在一起并重新编码。

我尝试过使用 agrep 和 stringdist 包。使用 agrep 我不确定我是否应该将每个地址作为一个模式并将其与其余地址匹配。从 stringdist 包中,我做了以下事情:

library(stringdist)
nsrpatt <- df$Address
x <- scan(what=character(), text = nsrpatt, sep=",")
x <- x[trimws(x)!= ""]
y <- ave(x, phonetic(x), FUN = function(.x) .x[1])

上面给了我错误:

In phonetic(x) : soundex encountered 111 non-printable ASCII or non-ASCII
  characters. 

不确定是否应该从字符向量中删除这些元素或将它们转换为其他格式。

我尝试使用 agrep:

for (i in 1:length(nsrpattn)) {
  npat <- agrep(nsrpattn[i], df$address, max=1, v=T)
}

字符向量的长度在 25000 左右,这会继续运行并停止机器。

如何有效地为每个地址找到最接近的匹配项。

【问题讨论】:

    标签: r pattern-matching stringdist agrep


    【解决方案1】:

    您可以对您的数据进行小型聚类分析。

    x <- c("wall street", "Wall-street", "Wall ST", "andheri pump house", 
           "weh, nr. pump house", "Wallstreet", "weh andheri pump house", 
           "Wall Street", "weh andheri pump house et", "andheri at weh pump house", 
           "andheri pump house(mt)")
    

    首先,您需要一个距离矩阵。

    # Levenstein Distance
    e  <- adist(na.omit(tolower(x)))
    rownames(e) <- na.omit(x)
    

    然后,可以运行聚类分析。

    hc <- hclust(as.dist(e))  # find distance clusters
    

    导出最佳切点,例如以图形方式,并“砍树”。

    plot(hc)
    

    # cut tree at specific cluster size, i.e. getting codes of similar objects
    smly <- cutree(hc, h=16)
    

    然后你可以建立一个关键数据框,你可以检查它是否匹配。

    key <- data.frame(x=na.omit(x), 
                      smly=factor(smly, labels=c("Wall Street", "Andheri Pump House")),
                      row.names=NULL)  # key data frame
    key
    #                            x               smly
    # 1                wall street        Wall Street
    # 2                Wall-street        Wall Street
    # 3                    Wall ST        Wall Street
    # 4         andheri pump house Andheri Pump House
    # 5        weh, nr. pump house Andheri Pump House
    # 6                 Wallstreet        Wall Street
    # 7     weh andheri pump house Andheri Pump House
    # 8                Wall Street        Wall Street
    # 9  weh andheri pump house et Andheri Pump House
    # 10 andheri at weh pump house Andheri Pump House
    # 11    andheri pump house(mt) Andheri Pump House
    

    最后像这样替换你的向量:

    x <- key$smly
    

    【讨论】:

    • 谢谢...听起来是个好主意...我会努力回来的。
    • 非常漂亮的方法。唯一的问题是 adist(x) 是 O(n^2),因此对于 25,000 个平均字符串长度为 30 个字符的字符串,这将花费 2 多个小时,至少在我的机器上是这样。不过,它是否有可能比 O(n^2) 做得更好并不明显。
    • 我在这里找到了另一个带有 agrep 的选项 https://stackoverflow.com/questions/24825215/group-together-levels-with-similar-names-r。将列表编号作为分类变量的组取消列出,通过匹配将其附加回数据框帮助我解决了问题。
    • @jay.sf 我会接受这个答案,它可以帮助我超越 agrep 和 amatch 的思考。
    猜你喜欢
    • 2016-06-11
    • 1970-01-01
    • 2021-11-18
    • 2017-04-15
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 2022-09-28
    • 2019-02-17
    相关资源
    最近更新 更多