【问题标题】:Text to columns by fixed width in RR中固定宽度的文本到列
【发布时间】:2020-02-03 15:03:28
【问题描述】:

我有一个大型数据框,我试图将一列中的值分成两列。这些值是字符然后是文本,例如 AU2847 或 AU1824。我希望第一列是 AU,第二列是对应的 4 位数字。

我也受限于基本的 r 包,所以我相信 strsplit 将是我们最好的选择 - 但无法弄清楚如何在第二个字符后拆分并从中创建 2 列。

【问题讨论】:

  • See here 提出一个人们可以帮助解决的 R 问题。这包括数据样本和所有必要的代码。

标签: r


【解决方案1】:

我经常使用这两个功能:

substrRight <- function(x, n){
  substr(x, nchar(x)-n+1, nchar(x))
}

substrLeft <- function(x, n){
  substr(x, 1,n)
}

在字符串的左边或右边截断n个字符

【讨论】:

    【解决方案2】:

    有几个选项可以做到这一点。您可以使用substr() 按位置进行子集化,也可以使用gsub() 并调用be reference。按位置进行子集化会更快但不灵活(您必须有一个巨大的数据框才能注意到时间差异),并且使用正则表达式(gsub() 会慢一点但更灵活)。例如:

    df[c("col2", "col3", "col2b", "col3b")] <- list(substr(df$col1, 1, 2),
                                                    substr(df$col1, 3, 6),
                                                    gsub("([[:alpha:]]+)(\\d+)", "\\1", df$col1),
                                                    gsub("([[:alpha:]]+)(\\d+)", "\\2", df$col1))
    
    df
        col1 col2 col3 col2b col3b
    1 AU2847   AU 2847    AU  2847
    2 AU1824   AU 1824    AU  1824
    

    数据

    df <- data.frame(col1 = c("AU2847", "AU1824"), stringsAsFactors = F)
    

    【讨论】:

      【解决方案3】:

      你可以试试:

      as.data.frame(
        do.call(rbind,
                strsplit(sub("^(.+?)(\\d+)", "\\1_\\2", df$col),
                         split="_")
                )
        )
      

      其中df 是您的数据框的名称,col 是您的列的名称。

      然后在文本和第一个数字之间人为插入下划线 - 这样您就可以使用下划线作为 strsplit 的参数。

      【讨论】:

        【解决方案4】:

        我们可以将strsplit() 与使用lookbehind 断言的正则表达式一起使用:

        x  <- c("AU2847", "AU1824")
        strsplit(x, "(?<=[A-Z]{2})", perl = TRUE)
        
        [[1]]
        [1] "AU"   "2847"
        
        [[2]]
        [1] "AU"   "1824"
        

        lookbehind 正则表达式告诉strsplit() 在两个大写字母之后分割每个字符串。无需像arg0naut91's answer 那样人为地引入要拆分的字符。


        现在,OP 已经提到要拆分的字符向量是更大数据帧的列。这需要一些额外的代码来将strsplit() 的列表输出作为新列附加到data.frame:

        假设我们有这个 data.frame

        DF <- data.frame(x, stringsAsFactors = FALSE)
        

        现在,可以通过以下方式附加新列:

        DF[, c("col1", "col2")] <- do.call(rbind, strsplit(DF$x, "(?<=[A-Z]{2})", perl = TRUE))
        DF
        
               x col1 col2
        1 AU2847   AU 2847
        2 AU1824   AU 1824
        

        【讨论】:

          猜你喜欢
          • 2023-02-05
          • 1970-01-01
          • 2021-02-18
          • 1970-01-01
          • 2012-06-10
          • 2012-08-27
          • 2013-01-01
          • 1970-01-01
          • 2010-12-16
          相关资源
          最近更新 更多