【问题标题】:Separate a string of multiple dates and names in R在R中分隔多个日期和名称的字符串
【发布时间】:2020-10-04 13:13:09
【问题描述】:

我有一个包含 2 列的数据框,其中第一列列出了公司,第二列是多个日期和公司名称的字符串,如下所示:

data=data.frame('Company'=(c("A","B","C")),
                'Bank'=c("1/13/2020 Bank A 5/12/2020 Bank H C 11/9/2020 HelloBank",
                         "2/14/2020 HopeBank 1/9/2020 Liberty Bank SA",
                         "10/18/2020 Securities"))

我想将“银行”列分成多列日期和银行名称,这样:

data=data.frame('Company'=(c("A","B","C")),
                "Date1"=(c("1/13/2020","2/14/2020","10/18/2020")),
                'Bank1'=c("Bank A", "HopeBank","Securities"),
                "Date2"=(c("5/12/2020","1/9/2020",NA)),
                'Bank2'=c("Bank H C", "Liberty Bank SA",NA),
                "Date3"=(c("11/9/2020 ",NA,NA)),
                'Bank3'=c("HelloBank", NA,NA))

我尝试过使用 library(stringr),但日期的格式并不一致。另外,我不知道最终数据帧中需要多少变量,并且“银行”列中的一些字符串很长(最多 824 个 nchar)。

我也尝试过使用与 tidyr 分开但没有成功。

【问题讨论】:

    标签: r string


    【解决方案1】:

    这是使用strsplit 制作的基本 R 选项

    v <- strsplit(data$Bank, "\\s(?=(\\d+\\/))|(?<=\\d)\\s", perl = TRUE)
    data <- cbind(
      data[1],
      `colnames<-`(
        do.call(rbind, lapply(v, `length<-`, max(lengths(v)))),
        paste0(c("Date", "Bank"), rep(1:(max(lengths(v)) / 2), each = 2))
      )
    )
    

    给了

    > data
      Company      Date1      Bank1     Date2           Bank2     Date3     Bank3
    1       A  1/13/2020     Bank A 5/12/2020        Bank H C 11/9/2020 HelloBank
    2       B  2/14/2020   HopeBank  1/9/2020 Liberty Bank SA      <NA>      <NA>
    3       C 10/18/2020 Securities      <NA>            <NA>      <NA>      <NA>
    

    【讨论】:

      【解决方案2】:

      如果您不知道每行可能有多少家银行,最好创建一个长格式的数据框。使用tidyverse...

      library(tidyverse)
      
      data_long <- data %>% 
        mutate(Bank = str_replace_all(Bank, "( \\d+/)", "#\\1"),  #add markers between banks
               Bank = str_split(Bank, "#")) %>%                   #split at markers
        unnest(Bank) %>%                                          #convert to one row per entry
        mutate(Bank = str_squish(Bank)) %>%                       #trim white space
        separate(Bank, into = c("Date", "BankName"), sep = " ", extra = "merge")
      
      data_long
      
        Company Date       BankName       
        <chr>   <chr>      <chr>          
      1 A       1/13/2020  Bank A         
      2 A       5/12/2020  Bank H C       
      3 A       11/9/2020  HelloBank      
      4 B       2/14/2020  HopeBank       
      5 B       1/9/2020   Liberty Bank SA
      6 C       10/18/2020 Securities     
      

      然后您可能希望将Date 转换为日期格式。

      如果你真的想要宽格式,请使用pivot_wider

      【讨论】:

      • 你比我先到了那里。 anytime::anydate() 会将所有日期转换为相同格式
      猜你喜欢
      • 1970-01-01
      • 2022-11-10
      • 2021-11-26
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 1970-01-01
      • 1970-01-01
      • 2020-11-15
      相关资源
      最近更新 更多