【问题标题】:How to extract text from a column using R如何使用R从列中提取文本
【发布时间】:2021-01-26 15:11:36
【问题描述】:

对于特定列中的每一行(Excel 文件中有大约 56,000 条记录),我将如何仅提取字符串的一部分?我需要将所有文本保留在最后一个“/”正斜杠的左侧。挑战在于并非所有单元格都具有相同数量的“/”。最后一个 '/' 的末尾总是有一个文件名 (*.wav),但文件名中的字符数并不总是相同(有时为 5,有时为 6)。

以下是单元格中字符串的一些示例:
cloch/51.wav
grand/Grand_bombarde/02-suchy_Grand_bombarde/038-D.wav
grand/Grand_bombarde/02-suchy_Grand_bombarde/039-D#.wav
AB_AeolinaL/025-C#.wav
AB_AeolinaL/026-D.wav
AB_violadamourL/rel99999/091-G.wav
AB_violadamourL/rel99999/092-G#.wav
AB_violadamourR/024-C.wav
AB_violadamourR/025-C#.wav

提取的文本应为:
钟形
盛大/Grand_bombarde/02-suchy_Grand_bombarde
盛大/Grand_bombarde/02-suchy_Grand_bombarde
AB_AeolinaL
AB_AeolinaL
AB_violadamourL/rel99999
AB_violadamourL/rel99999
AB_violadamourR
AB_violadamourR

谁能推荐使用 R 的策略?

【问题讨论】:

    标签: r string extract


    【解决方案1】:

    您可以使用stringr 包str_remove(string,pattern) 函数,如:

    str = "grand/Grand_bombarde/02-suchy_Grand_bombarde/038-D.wav"
    str_remove(str,"/[0-9]+[-]*[A-Z]*[#]*[.][a-z]+")
    

    输出:

    > str_remove(str,"/[0-9]+[-]*[A-Z]*[#]*[.][a-z]+")
    [1] "grand/Grand_bombarde/02-suchy_Grand_bombarde"
    

    然后你可以遍历所有其他字符串:

    strings <- c("cloch/51.wav",
                 "grand/Grand_bombarde/02-suchy_Grand_bombarde/038-D.wav",
                 "grand/Grand_bombarde/02-suchy_Grand_bombarde/039-D#.wav",
                 "AB_AeolinaL/025-C#.wav",
                 "AB_AeolinaL/026-D.wav",
                 "AB_violadamourL/rel99999/091-G.wav",
                 "AB_violadamourL/rel99999/092-G#.wav",
                 "AB_violadamourR/024-C.wav",
                 "AB_violadamourR/025-C#.wav")
    str_remove(strings,"/[0-9]+[-]*[A-Z]*[#]*[.][a-z]+")
    

    输出:

    > str_remove(strings,"/[0-9]+[-]*[A-Z]*[#]*[.][a-z]+")
    [1] "cloch"                                       
    [2] "grand/Grand_bombarde/02-suchy_Grand_bombarde"
    [3] "grand/Grand_bombarde/02-suchy_Grand_bombarde"
    [4] "AB_AeolinaL"                                 
    [5] "AB_AeolinaL"                                 
    [6] "AB_violadamourL/rel99999"                    
    [7] "AB_violadamourL/rel99999"                    
    [8] "AB_violadamourR"                             
    [9] "AB_violadamourR"  
    

    【讨论】:

    • 我也更喜欢删除字符串而不是 substr 方法,因为这允许您保留没有/ 的情况,而无需额外的代码来捕获这些情况,但为什么不直接使用 base R:gsub("/[0-9]+[-]*[A-Z]*[#]*[.][a-z]+", "", strings)?
    • 我一直在使用很多 stringr 软件包,以至于 gsub() 完全让我忘记了。虽然我想我在某处读到 stringr 和 stringi 比基本包快一点。
    • 至少对于这个特定的示例,gsub 似乎快了 3 倍,但我们在这里讨论的是微秒,所以这并不重要。只是说你不需要额外的包......
    【解决方案2】:

    你必须使用这个方法减去字符串:

    substr(strings,1,regexpr("\\/[^\\/]*$", strings)-1)
    [1] "cloch"                                       
    [2] "grand/Grand_bombarde/02-suchy_Grand_bombarde"
    [3] "grand/Grand_bombarde/02-suchy_Grand_bombarde"
    [4] "AB_AeolinaL"                                 
    [5] "AB_AeolinaL"                                 
    [6] "AB_violadamourL/rel99999"                    
    [7] "AB_violadamourL/rel99999"                    
    [8] "AB_violadamourR"                             
    [9] "AB_violadamourR"
    

    输入

    strings<-c("cloch/51.wav","grand/Grand_bombarde/02-suchy_Grand_bombarde/038-D.wav","grand/Grand_bombarde/02-suchy_Grand_bombarde/039-D#.wav","AB_AeolinaL/025-C#.wav","AB_AeolinaL/026-D.wav","AB_violadamourL/rel99999/091-G.wav","AB_violadamourL/rel99999/092-G#.wav","AB_violadamourR/024-C.wav","AB_violadamourR/025-C#.wav")
    

    这个正则表达式regexpr("\\/[^\\/]*$", strings) 为您提供最后一个“/”的位置

    【讨论】:

      【解决方案3】:

      假设您建议的字符串位于数据框的列中:

      df <- data.frame(x = 1:5, y = c("cloch/51.wav", 
                                      "grand/Grand_bombarde/02-suchy_Grand_bombarde/038-D.wav", 
                                      "grand/Grand_bombarde/02-suchy_Grand_bombarde/039-D#.wav", 
                                      "AB_AeolinaL/025-C#.wav", 
                                      "AB_AeolinaL/026-D.wav"))
      
      # I define a function that separates a string at each "/" 
      # throws the last piece and reattaches the pieces
      
      cut_str <- function(s) {
        st <- head((unlist(strsplit(s, "\\/"))), -1)
        r <- paste(st, collapse = "/")
        return(r)
      }
      
      # through the sapply function I get the desired result
      
      new_strings <- as.vector(sapply(df$y, FUN = cut_str))
      new_strings
      
      [1] "cloch"                                       
      [2] "grand/Grand_bombarde/02-suchy_Grand_bombarde"
      [3] "grand/Grand_bombarde/02-suchy_Grand_bombarde"
      [4] "AB_AeolinaL"                                 
      [5] "AB_AeolinaL" 
      

      【讨论】:

        【解决方案4】:

        你可以使用

        dirname(strings)
        

        如果没有/,则返回.,如果你愿意,可以在之后删除它,例如:

        res <- dirname(strings)
        res[res=="."] <- ""
        ``
        

        【讨论】:

          【解决方案5】:

          您可以使用 / 开始匹配,后跟 1 次或多次除正斜杠或使用否定字符类 [^\\s/]+ 的空白字符之外的任何字符

          然后使用$匹配字符串末尾的.wav

          例如,使用 sub 将匹配替换为空字符串。

          [^\\s/]+\\.wav$

          See the regex matches | R demo

          strings <- c("cloch/51.wav",
                       "grand/Grand_bombarde/02-suchy_Grand_bombarde/038-D.wav",
                       "grand/Grand_bombarde/02-suchy_Grand_bombarde/039-D#.wav",
                       "AB_AeolinaL/025-C#.wav",
                       "AB_AeolinaL/026-D.wav",
                       "AB_violadamourL/rel99999/091-G.wav",
                       "AB_violadamourL/rel99999/092-G#.wav",
                       "AB_violadamourR/024-C.wav",
                       "AB_violadamourR/025-C#.wav")
          
          sub("/[^\\s/]+\\.wav$", "", strings)
          

          输出

          [1] "cloch"                                       
          [2] "grand/Grand_bombarde/02-suchy_Grand_bombarde"
          [3] "grand/Grand_bombarde/02-suchy_Grand_bombarde"
          [4] "AB_AeolinaL"                                 
          [5] "AB_AeolinaL"                                 
          [6] "AB_violadamourL/rel99999"                    
          [7] "AB_violadamourL/rel99999"                    
          [8] "AB_violadamourR"                             
          [9] "AB_violadamourR"
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-04-23
            • 1970-01-01
            • 2012-02-17
            • 2022-01-22
            • 1970-01-01
            • 1970-01-01
            • 2021-04-19
            • 1970-01-01
            相关资源
            最近更新 更多