【问题标题】:How to split a string after the nth character in r如何在r中的第n个字符之后拆分字符串
【发布时间】:2020-05-21 20:30:42
【问题描述】:

我正在处理以下数据:

District <- c("AR01", "AZ03", "AZ05", "AZ08", "CA01", "CA05", "CA11", "CA16", "CA18", "CA21")

我想在第二个字符之后拆分字符串并将它们分成两列。

让数据看起来像这样:

state  district
AR        01
AZ        03
AZ        05
AZ        08
CA        01
CA        05
CA        11
CA        16
CA        18
CA        21

有没有简单的代码来完成这项工作?非常感谢您的帮助

【问题讨论】:

  • 你看过substr吗?
  • 我没有。我比较熟悉strsplit()。但是由于没有什么可拆分的,因此在这种情况下不适用

标签: r string split data-management


【解决方案1】:

如果你总是想用第二个字符分割,你可以使用substr

District <- c("AR01", "AZ03", "AZ05", "AZ08", "CA01", "CA05", "CA11", "CA16", "CA18", "CA21")
#split district  starting at the first and ending at the second
state <- substr(District,1,2)
#split district starting at the 3rd and ending at the 4th
district <- substr(District,3,4)
#put in data frame if needed.
st_dt <- data.frame(state = state, district = district, stringsAsFactors = FALSE)

【讨论】:

  • 这很有帮助!感谢您提供代码和注释。
【解决方案2】:

您可以使用基础 R 中的strcapture

 strcapture("(\\w{2})(\\w{2})",District,
                    data.frame(state = character(),District = character()))
   state District
1     AR       01
2     AZ       03
3     AZ       05
4     AZ       08
5     CA       01
6     CA       05
7     CA       11
8     CA       16
9     CA       18
10    CA       21

\\w{2} 表示两个词

【讨论】:

    【解决方案3】:

    我们可以使用str_match 将前两个字符和剩余的字符串捕获在不同的列中。

    stringr::str_match(District, "(..)(.*)")[, -1]
    
    #      [,1] [,2]
    # [1,] "AR" "01"
    # [2,] "AZ" "03"
    # [3,] "AZ" "05"
    # [4,] "AZ" "08"
    # [5,] "CA" "01"
    # [6,] "CA" "05"
    # [7,] "CA" "11"
    # [8,] "CA" "16"
    # [9,] "CA" "18"
    #[10,] "CA" "21"
    

    【讨论】:

      【解决方案4】:

      OP 有written

      我更熟悉strsplit()。但既然没有什么可分割的 on,在这种情况下不适用

      Au contraire! 有一些东西要分开,它被称为 lookbehind

      strsplit(District, "(?<=[A-Z]{2})", perl = TRUE) 
      

      lookbehind 的工作方式类似于“插入一个不可见的中断”在 2 个大写字母之后并在那里拆分字符串。

      结果是一个向量列表

      [[1]]
      [1] "AR" "01"
      
      [[2]]
      [1] "AZ" "03"
      
      [[3]]
      [1] "AZ" "05"
      
      [[4]]
      [1] "AZ" "08"
      
      [[5]]
      [1] "CA" "01"
      
      [[6]]
      [1] "CA" "05"
      
      [[7]]
      [1] "CA" "11"
      
      [[8]]
      [1] "CA" "16"
      
      [[9]]
      [1] "CA" "18"
      
      [[10]]
      [1] "CA" "21"
      

      可以转化为矩阵,例如,通过

      do.call(rbind, strsplit(District, "(?<=[A-Z]{2})", perl = TRUE))
      
            [,1] [,2]
       [1,] "AR" "01"
       [2,] "AZ" "03"
       [3,] "AZ" "05"
       [4,] "AZ" "08"
       [5,] "CA" "01"
       [6,] "CA" "05"
       [7,] "CA" "11"
       [8,] "CA" "16"
       [9,] "CA" "18"
      [10,] "CA" "21"
      

      【讨论】:

        【解决方案5】:

        把它当作定宽文件,然后导入:

        # read fixed width file
        read.fwf(textConnection(District), widths = c(2, 2), colClasses = "character")
        #    V1 V2
        # 1  AR 01
        # 2  AZ 03
        # 3  AZ 05
        # 4  AZ 08
        # 5  CA 01
        # 6  CA 05
        # 7  CA 11
        # 8  CA 16
        # 9  CA 18
        # 10 CA 21
        

        【讨论】:

          【解决方案6】:

          有了tidyverse,这很容易使用来自tidyr的函数separate

          library(tidyverse)
          District %>% 
            as.tibble() %>% 
            separate(value, c("state", "district"), sep = "(?<=[A-Z]{2})")
          
          # A tibble: 10 × 2
             state district
             <chr> <chr>   
           1 AR    01      
           2 AZ    03      
           3 AZ    05      
           4 AZ    08      
           5 CA    01      
           6 CA    05      
           7 CA    11      
           8 CA    16      
           9 CA    18      
          10 CA    21      
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-03-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多