R中的部分字符串匹配和替换

3

I have a dataframe like this

> myDataFrame
           company
1   Investment LLC
2    Hyperloop LLC
3 Invezzstment LLC
4   Investment_LLC
5   Haiperloop LLC
6   Inwestment LLC

我需要匹配所有这些模糊字符串,因此最终结果应该像这样:
> myDataFrame
           company
1   Investment LLC
2    Hyperloop LLC
3   Investment LLC
4   Investment LLC
5    Hyperloop LLC
6   Investment LLC

实际上,我需要解决一个针对分类变量的部分匹配和替换任务。在base R和packages中有很多强大的函数来解决字符串匹配问题,但我却无法找到单一的解决方案来处理这种匹配和替换。

我不关心哪个匹配项将替换其他匹配项,例如"Investment LLC"或"Invezzstment LLC"都可以。只需要它们是一致的即可。

是否有任何单一的一体化函数或循环来实现这一点?


你能描述一下你目前尝试了什么吗?例如,为什么 base::agrep 对你来说不起作用? - Calimo
亲爱的@Calimo,base :: agrep在查找相似字符串方面工作得非常好,但我无法强制它逐行替换字符串。我尝试了一些for和while循环,但没有成功。算法应该如下:1)R在向量中查找一个字符串2)将其与向量中的其他字符串进行比较3)与它相似(提供一些距离测量)的每个字符串都必须被替换为该字符串。 - user16
请发布您已经拥有的代码,这样我们就可以从那里开始。顺便说一下,我从您对答案的评论中了解到选择拼写错误的"Invezzstment LLC"也可以吗? - Calimo
@Calimo,我删除了这段代码,不幸的是,在提交时它没有被保存在我的git中。无论如何,它几乎没有什么用处,因为它是无效的。我记得我使用了 sapply和部分匹配函数(我想是agrep)。 "Invezzstment LLC"完全没问题。事实上,Invezzstment LLC和Investment LLC是同一件事;我需要R来获取任何一个并替换所有其他出现的内容,以便我有一个漂亮的分类变量用于此类别。当您拥有超过50000条记录和1200个唯一值时,找出任何拼写错误的变量都是一项繁琐的工作。 - user16
2个回答

0

所以,经过一段时间的努力,我最终得到了这个愚蠢的代码。注意:它并没有完全自动化替换的过程,因为每次都需要人工验证正确的匹配,并且每次我们需要微调 agrep 的 max.distance 参数。我完全确定有更好、更快的方法,但这可以帮助完成工作。

    ##########
    # Manual renaming with partial matches
    ##########

    # a) Take a look at the desired column of factor variables
    sort(unique(MYDATA$names))   # take a look

    # ****
    Sensthreshold <- 0.2   # sensitivity of agrep, usually 0.1-0.2 get it right
    Searchstring <- "Invesstment LLC"   # what should I search?
    # ****

    # User-defined function: returns similar string on query in column
    Searcher <- function(input, similarity = 0.1) {
      unique(agrep(input, 
                   MYDATA$names,   # <-- define your column here
                   ignore.case = TRUE, value = TRUE,
                   max.distance = similarity))
    }

    # b) Make a search of desired string
    Searcher(Searchstring, Sensthreshold)   # using user-def function 
    ### PLEASE INSPECT THE OUTPUT OF THE SEARCH
    ### Did it get it right?

 =============================================================================#
    ## ACTION! This changes your dataframe!
    ## Please make backup before proceeding
    ## Please execute this code as a whole to avoid errors

    # c) Make a vector of cells indexes after checking output
    vector_of_cells <- agrep(Searchstring, 
                       MYDATA$names, ignore.case = TRUE,
                       max.distance = Sensthreshold)
    # d) Apply the changes
    MYDATA$names[vector_of_cells] <- Searchstring # <--- CHANGING STRING
    # e) Check result
    unique(agrep(Searchstring, MYDATA$names, 
                 ignore.case = TRUE, value = TRUE, max.distance = Sensthreshold))
=============================================================================#

0
如果您有一个正确拼写的向量,agrep 可以使这个过程相对容易:
myDataFrame$company <- sapply(myDataFrame$company, 
                              function(val){agrep(val, 
                                                  c('Investment LLC', 'Hyperloop LLC'), 
                                                  value = TRUE)})

myDataFrame
#          company
# 1 Investment LLC
# 2  Hyperloop LLC
# 3 Investment LLC
# 4 Investment LLC
# 5  Hyperloop LLC
# 6 Investment LLC

如果你没有这样的向量,你可能可以巧妙地应用adist甚至只是table来创建一个,如果正确的拼写重复出现的次数超过其他单词,那么它很可能会出现(虽然这里没有)。


谢谢您的回复,alistaire!我没有正确拼写实体向量。我尝试了您有关adist函数的建议,但是,由于记录数=59396,因此R无法计算此字符串距离矩阵,因此这个大型矩阵对象超出了26.3 Gb。表格是个好主意,我会试一试。 - user16

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接