【问题标题】:Extract characters bound by parentheses提取括号内的字符
【发布时间】:2019-05-14 05:20:00
【问题描述】:

我有从 .csv 文件导入的数据。第一列包含包含括号内的文本的字符串。数据如下:

    symbol
    ___________________________________________
1 | Apollo Senior Floating Rate Fund Inc. (AFT)
2 | Apollo Tactical Income Fund Inc. (AIF)
3 | Altra Industrial Motion Corp. (AIMC)
4 | Allegion plc (ALLE) 
5 | Amphenol Corporation (APH)
6 | Ares Management Corporation (ARES)
7 | ARMOUR Residential REIT, Inc. (ARR)
8 | Banc of California, Inc. (BANC)
9 | BlackRock Resources (BCX)
10| Belden Inc (BDC)
...

我需要将该列数据转换成一个列表,例如:

    symbol2
    ___________________________________________
1 | AFT
2 | AIF
3 | AIMC
4 | ALLE
5 | APH
6 | ARES
7 | ARR
8 | BANC
9 | BCX
10| BDC
...

我的最终目标是获得一个字符串,其中由括号绑定的文本由“;”分隔像这样:

"AFT;AIF;AIMC;ALLE;APH;ARES;ARR;BANC;BCX;BDC;..."

我可以用

完成这最后一步
paste(symbol2, collapes = ";")

但我不知道如何隔离所需的文本。

我已经尝试了此处列出的所有内容 (extract a substring in R according to a pattern),方法是将“:”替换为“(”,但无法正常工作。我尝试过:

gsub("(?<=\\()[^()]*(?=\\))(*SKIP)(*F)|.", "", symbol, perl=T)

这里推荐(Extract text in parentheses in R),但输出是

"c(4, 5, 2, 1, 3, 6, 7, 8, 17, 9,...)"

有什么帮助吗?

【问题讨论】:

    标签: r regex string character parentheses


    【解决方案1】:

    我们可以使用str_extractstringr中提取内容

    library(stringr)
    symbol2 <- str_extract(df$symbol, "(?<=\\().+?(?=\\))")
    symbol2
    #[1] "AFT"  "AIF"  "AIMC" "ALLE" "APH"  "ARES"
    

    正则表达式取自here

    然后你可以paste他们一起

    paste(symbol2, collapse = ";")
    #[1] "AFT;AIF;AIMC;ALLE;APH;ARES"
    

    【讨论】:

      【解决方案2】:

      这是一个使用基本 R 的 sub 和捕获组的选项

      df$symbol2 <- sub(".+\\((\\w+)\\)$", "\\1", df$V1)
      df
      #                                            V1 symbol2
      #1  Apollo Senior Floating Rate Fund Inc. (AFT)     AFT
      #2       Apollo Tactical Income Fund Inc. (AIF)     AIF
      #3         Altra Industrial Motion Corp. (AIMC)    AIMC
      #4                          Allegion plc (ALLE)    ALLE
      #5                   Amphenol Corporation (APH)     APH
      #6           Ares Management Corporation (ARES)    ARES
      #7          ARMOUR Residential REIT, Inc. (ARR)     ARR
      #8              Banc of California, Inc. (BANC)    BANC
      #9                    BlackRock Resources (BCX)     BCX
      #10                            Belden Inc (BDC)     BDC 
      

      样本数据

      df <- read.table(text =
      "'Apollo Senior Floating Rate Fund Inc. (AFT)'
      'Apollo Tactical Income Fund Inc. (AIF)'
      'Altra Industrial Motion Corp. (AIMC)'
      'Allegion plc (ALLE)'
      'Amphenol Corporation (APH)'
      'Ares Management Corporation (ARES)'
      'ARMOUR Residential REIT, Inc. (ARR)'
      'Banc of California, Inc. (BANC)'
      'BlackRock Resources (BCX)'
      'Belden Inc (BDC)'", header = F)
      

      【讨论】:

        【解决方案3】:

        1) read.tableread.table 与指定的sepcomment 值一起使用以获取2 列数据框,其中第一列是名称,第二列是符号。最后取第二列并将其折叠成一个字符串。不使用任何包或正则表达式。

        DF2 <- read.table(text = unlist(DF), sep = "(", comment = ")")
        paste(DF2[[2]], collapse = ";")
        ## [1] "AFT;AIF;AIMC;ALLE;APH;ARES;ARR;BANC;BCX;BDC"
        

        2) dplyr 我们可以使用 tidyr 中的separate 来分隔名称列和符号列,同时删除名称列。 unlist 并将其折叠成一个字符串。必须使用 tidyr 0.8.2 或更高版本。

        library(dplyr)
        library(tidyr)
        
        DF %>%
          separate(symbol, c(NA, "symbol2"), "[()]", extra = "drop") %>%
          unlist %>%
          paste(collapse = ";")
        ## [1] "AFT;AIF;AIMC;ALLE;APH;ARES;ARR;BANC;BCX;BDC"
        

        3) gsub 我们可以匹配所有内容,包括 (,即".*\\(" 以及从 ) 开始的所有内容,即"\\).*",并将它们替换为空字符串。然后像以前一样折叠。

        paste(gsub(".*\\(|\\).*", "", DF$symbol), collapse = ";")
        ## [1] "AFT;AIF;AIMC;ALLE;APH;ARES;ARR;BANC;BCX;BDC"
        

        4) trimws 这是另一个基本解决方案。它需要 R 3.6.0 或更高版本(当前为 r-devel)。我们将空格定义为括号以外的任何内容,并使用trimws 将其修剪掉。然后我们将空格定义为括号,然后将其修剪掉。这给我们留下了现在可以折叠的符号。

        paste(trimws(trimws(DF$symbol, white = "[^()]"), white = "[()]"), collapse = ";")
        ## [1] "AFT;AIF;AIMC;ALLE;APH;ARES;ARR;BANC;BCX;BDC"
        

        注意

        可重现形式的输入是:

        Lines <- "
            symbol
        1 | Apollo Senior Floating Rate Fund Inc. (AFT)
        2 | Apollo Tactical Income Fund Inc. (AIF)
        3 | Altra Industrial Motion Corp. (AIMC)
        4 | Allegion plc (ALLE) 
        5 | Amphenol Corporation (APH)
        6 | Ares Management Corporation (ARES)
        7 | ARMOUR Residential REIT, Inc. (ARR)
        8 | Banc of California, Inc. (BANC)
        9 | BlackRock Resources (BCX)
        10| Belden Inc (BDC)"
        DF <- read.table(text = Lines, sep = "|", strip.white = TRUE, as.is = TRUE)
        

        【讨论】:

        • 另一种 data.table 方式! paste(tstrsplit(DF$symbol, '\\(|\\)')[[2]], collapse = ';')
        猜你喜欢
        • 2016-12-24
        • 1970-01-01
        • 2016-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-02
        • 1970-01-01
        • 2014-09-05
        相关资源
        最近更新 更多