【问题标题】:Replace rules(String pattern matching) in RR中的替换规则(字符串模式匹配)
【发布时间】:2020-02-15 06:00:28
【问题描述】:

我知道在这个论坛上可能会提出类似的问题,但我觉得我的要求很特殊。 我有一个数据框,其中有一列具有以下值。 下面是刚刚的样本,它包含 1000 多个观察结果

报告的条款

"2 Left Axillary Lymph Nodes Resection"             
"cardyoohyper"                                      
"Ablation Breast"                                    
"Hypercarido"                                       
"chordiohyper"                                       
"Adenocarcinoma Of Colon (Radical Resection And Cr)"
"myocasta"
"hypermyopa"

我有另一个具有以下规则的数据框:

数据框

我期待以下输出:

"2 Left Axillary Lymph Nodes Resection"             
"carddiohiper"                                      
"Ablation Breast"                                    
"hipercardio"                                       
"cardiohyper"                                       
"Adenocarcinoma Of Colon (Radical Resection And Cr)"
"miocasta"
"hipermiopa"

我正在尝试使用 gsub 函数进行热编码,但我知道这需要很长时间。

pattern <- c("kardio, "carido", "cardyo", "cordio", "chordio")
replacement <- "cardio"
gusub(pattern,replacement,df$reportedterms)

使用上述方法,我需要每次对每个规则进行编码,并且每次都需要为 gsub 函数中的模式和替换创建不同的变量。

有解决这个问题的简单方法吗?

【问题讨论】:

    标签: r replace pattern-matching stringr stringi


    【解决方案1】:

    首先让我们按照您的描述进行设置:

    library(tibble)
    
    df <- tibble(text = c("2 Left Axillary Lymph Nodes Resection",
                          "cardyoohyper",
                          "Ablation Breast",
                          "Hypercarido",
                          "chordiohyper",
                          "Adenocarcinoma Of Colon (Radical Resection And Cr)",
                          "myocasta",
                          "hypermyopa"))
    
    replace_dict <- tibble(pattern = list(c("kardio", "carido", "cardyo", "cordio", "chordio"), 
                                          "myoca",
                                          "myopa",
                                          "hyper"),
                           replacement = c("cardio", 
                                           "mioca",
                                           "miopa",
                                           "hiper"))
    

    我会简单地使用stringi 来完成任务,因为它有一个非常有效的gsub 版本,即stri_replace_all_fixed(请注意,您也可以使用正则表达式版本,它有点慢但工作方式相同) .它可以同时处理多个模式和替换,所以我们需要做的就是先取消模式列,然后运行stringi

    batch_replace <- function(text, replace_dict) {
    
      replace_dict <- tidyr::unnest(replace_dict, pattern) 
    
      stringi::stri_replace_all_fixed(str = text, 
                                      pattern = replace_dict$pattern, 
                                      replacement = replace_dict$replacement, 
                                      vectorize_all = FALSE)
    }
    

    让我们测试一下这个函数:

    df$text_new <- batch_replace(df$text, replace_dict)
    df
    #> # A tibble: 8 x 2
    #>   text                                 text_new                            
    #>   <chr>                                <chr>                               
    #> 1 2 Left Axillary Lymph Nodes Resecti~ 2 Left Axillary Lymph Nodes Resecti~
    #> 2 cardyoohyper                         cardioohiper                        
    #> 3 Ablation Breast                      Ablation Breast                     
    #> 4 Hypercarido                          Hypercardio                         
    #> 5 chordiohyper                         cardiohiper                         
    #> 6 Adenocarcinoma Of Colon (Radical Re~ Adenocarcinoma Of Colon (Radical Re~
    #> 7 myocasta                             miocasta                            
    #> 8 hypermyopa                           hipermiopa
    

    我想这就是你想要的。请注意,该功能不是很灵活,因为您必须完全按照所示方式提供stri_replace_all_fixed。由于您尚未共享文件,因此我无法帮助您解决该表单,因此您必须弄清楚这一点或提出一个新问题。

    更新

    如果您希望替换不区分大小写并且还希望将文本小写,则该函数可能如下所示:

    batch_replace <- function(text, replace_dict, to_lower = TRUE, case_insensitive = TRUE) {
    
      replace_dict <- tidyr::unnest(replace_dict, pattern) 
    
      if (to_lower) {
        text <- tolower(text)
      }
    
      stringi::stri_replace_all_fixed(str = text, 
                                      pattern = replace_dict$pattern, 
                                      replacement = replace_dict$replacement, 
                                      vectorize_all = FALSE,
                                      opts_fixed = stringi::stri_opts_fixed(case_insensitive = case_insensitive))
    }
    

    您可以根据需要打开/关闭小写字母和不区分大小写的替换。

    【讨论】:

    • 谢谢,但在一种情况下,我想替换错误的单词,仅以字符串的 hyper 开头。例如,“hypercardio”应该替换为“hipercardio”,但在另一种情况下,“cardiohyper”不应该替换为“cardiohiper”,它应该保持为“cardiohyper”..无论如何要这样做
    • 您可以改用stri_replace_all_regex,然后使用正则表达式"\\bhyper"作为模式。这意味着“hyper”必须位于单词的开头才能被替换。 \\b 是一个词的边界,也可以用来表示一个词的结尾。仅当它出现在单词 "hyper\\b" 的末尾时,它才会替换“hyper”。
    • 这是否解决了您的问题?我的回答对你有用吗?
    • 抱歉延迟回复,我在过去的 3 周里一直生病。我尝试如下 replace_dict
    • 这对我很有帮助。谢谢
    猜你喜欢
    • 2013-10-24
    • 2014-12-27
    • 1970-01-01
    • 2020-07-12
    • 2014-08-20
    • 1970-01-01
    • 2014-03-22
    • 2012-10-13
    • 1970-01-01
    相关资源
    最近更新 更多