【问题标题】:How to separate a column in R with unequal character lengths and without separators如何在 R 中分隔字符长度不等且没有分隔符的列
【发布时间】:2020-02-13 17:13:19
【问题描述】:

我想将包含日期和项目的列分成两列。

V1
23/2/2000shampoo
24/2/2000flour
21/10/2000poultry
17/4/2001laundry detergent

到这里

V1           V2
23/2/2000    shampoo
24/2/2000    flour
21/10/2000   poultry
17/4/2001    laundry detergent

我的问题是两者之间没有分离。日期长度不统一(格式为 2000 年 1 月 1 日而不是 2000 年 1 月 1 日),因此我无法按字符长度分隔。该数据集还涵盖多年。

【问题讨论】:

    标签: r tidyverse tidyr


    【解决方案1】:

    一个选项是separate 来自tidyr。我们使用正则表达式环视来指定sep,以在数字和小写字母之间进行分割

    library(dplyr)
    library(tidyr)
    df1 %>%
       separate(V1, into = c("V1", "V2"), sep="(?<=[0-9])(?=[a-z])")
    #        V1                V2
    #1  23/2/2000           shampoo
    #2  24/2/2000             flour
    #3 21/10/2000           poultry
    #4  17/4/2001 laundry detergent
    

    或在使用sub 创建分隔符后使用read.csv

    read.csv(text = sub("(\\d)([a-z])", "\\1,\\2", df1$V1), 
             header = FALSE, stringsAsFactors = FALSE)
    

    数据

    df1 <- structure(list(V1 = c("23/2/2000shampoo", "24/2/2000flour", 
          "21/10/2000poultry", 
    "17/4/2001laundry detergent")), class = "data.frame", row.names = c(NA, 
    -4L))
    

    【讨论】:

    • 谢谢,这正是我想要的。
    【解决方案2】:

    您还可以通过tidyr::extract() 使用捕获组。第一组\\d{1,2}/\\d{1,2}/\\d{4} 以您发布的格式获取日期,第二组[[:print:]]+ 获取至少一个可打印字符。

    library(tidyverse)
    
    df1 %>%
      extract(V1, c("V1", "V2"), "(\\d{1,2}/\\d{1,2}/\\d{4})([[:print:]]+)")
              V1                V2
    1  23/2/2000           shampoo
    2  24/2/2000             flour
    3 21/10/2000           poultry
    4  17/4/2001 laundry detergent
    

    数据

    df1 <- readr::read_csv("V1
    23/2/2000shampoo
    24/2/2000flour
    21/10/2000poultry
    17/4/2001laundry detergent")
    

    【讨论】:

      【解决方案3】:

      你也可以使用:

      data <- data.frame(V1 = c("23-02-2000shampoo", "24-02-2001flour"))
      
      library(stringr)
      str_split_fixed(data$V1, "(?<=[0-9])(?=[a-z])", 2)
      
           [,1]         [,2]     
      [1,] "23-02-2000" "shampoo"
      [2,] "24-02-2001" "flour"  
      

      【讨论】:

      • 错字:你用v1创建了数据框,但是用V1分割它
      • @Gainz 可以在base R 中使用相同的代码。 strsplitdo.call(rbind, strsplit(as.character(data$V1), "(?&lt;=[0-9])(?=[a-z])", perl = TRUE))
      • @akrun 是的!我没想到你是对的。我只是习惯了 stringr 包,因为它在处理我使用的数据(500+ 数百万行)上比基础 R 快得多。非常感谢!
      • @Gainz stringr 环绕 stringi 并且 stringi 非常快 :=)
      • @akrun 是的,这绝对是一个了不起的包!
      猜你喜欢
      • 2018-03-31
      • 2020-01-15
      • 2021-05-30
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 2019-02-17
      • 1970-01-01
      • 2013-06-07
      相关资源
      最近更新 更多