【问题标题】:arrange date characters in R在R中排列日期字符
【发布时间】:2022-01-22 09:50:05
【问题描述】:

我正在处理许多在括号中标有年份的 csv 文件。例如:

files_names <- list.files("data/", recursive = TRUE, full.names = TRUE)

[1] "data/BOC_All_ATMImage_(Aug 2020).txt" "data/BOC_All_ATMImage_(Aug 2021).txt"
[3] "data/BOC_All_ATMImage_(Feb 2021).txt" "data/BOC_All_ATMImage_(Feb_2020).txt"
[5] "data/BOC_All_ATMImage_(May 2021).txt" "data/BOC_All_ATMImage_(Nov 2019).txt"

column_names <- files_names %>%
  str_extract(., "(?<=\\().*?(?=\\))") %>%
  str_to_lower() %>%
  str_replace(., " ", "_")

"aug_2020" "aug_2021" "feb_2021" "feb_2020" "may_2021" "nov_2019"

我正在使用purrr 中的map2 函数来处理csv 文件,并在循环中使用files_namescolumn_names 设置列名。

data <-
  map2(files_names, column_names,
       ~ read_csv(.x, guess_max = 50000) %>%
         mutate(
           day = 01,
           month_year = str_extract(.x, "(?<=\\().*?(?=\\))"),
           date_dmy = paste0(day, "-", month_year),
           date = dmy(date_dmy),
           "{.y}" := 1
         ),
       .id = "group" 
  )

我需要弄清楚如何排列这个列表,以便每个数据集都按时间顺序排列。一种方法是在将初始字符向量(files_namescolumn_names)输入循环之前对其进行排列。或者简单地排列data 列表以便数据帧按时间顺序排列可能更容易?我在每个数据框中创建了一个 date 变量,所以这可能是另一种方法,但我不确定如何按日期变量重新排序列表。

【问题讨论】:

    标签: r dplyr purrr


    【解决方案1】:

    我们可以使用str_match 来搜索月份和年份。之后,使用一些dplyr 来清理数据。安排我想到使用因子的月份。

    library(tidyverse)
    
    files_names <-
      c(
        "data/BOC_All_ATMImage_(Aug 2020).txt", "data/BOC_All_ATMImage_(Aug 2021).txt",
        "data/BOC_All_ATMImage_(Feb 2021).txt", "data/BOC_All_ATMImage_(Feb_2020).txt",
        "data/BOC_All_ATMImage_(May 2021).txt", "data/BOC_All_ATMImage_(Nov 2019).txt"
      )
    
    factor_w_month <- partial(factor, levels = )
    months <- partial(factor, levels = (c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")))
    
    files_names %>%
      str_match(".*_\\((.*)[ _](\\d+)\\)\\.txt$") %>%
        as.data.frame() %>%
        mutate(V2 = months(V2)) %>%
        arrange(V3, V2) %>% 
        transmute(files_names = V1, column_names = str_to_lower(str_c(V2, '_', V3)))
    #>                            files_names column_names
    #> 1 data/BOC_All_ATMImage_(Nov 2019).txt     nov_2019
    #> 2 data/BOC_All_ATMImage_(Feb_2020).txt     feb_2020
    #> 3 data/BOC_All_ATMImage_(Aug 2020).txt     aug_2020
    #> 4 data/BOC_All_ATMImage_(Feb 2021).txt     feb_2021
    #> 5 data/BOC_All_ATMImage_(May 2021).txt     may_2021
    #> 6 data/BOC_All_ATMImage_(Aug 2021).txt     aug_2021
    

    reprex package (v2.0.1) 于 2021 年 12 月 20 日创建

    【讨论】:

      【解决方案2】:

      我认为以下解决方案还可以帮助您在开始将日期读入 R 之前对其进行排序:

      library(dplyr)
      library(stringr)
      
      files_names %>%
        enframe() %>%
        mutate(date = str_extract(value, "(?<=\\().*(?=\\))"), 
               date = paste(str_extract(date, "\\d+"), str_extract(date, "[[:alpha:]]+"), "01", 
                            sep = "-"), 
               date = as.Date(date, format = "%Y-%b-%d")) %>%
        arrange(desc(date))
      
      # A tibble: 6 x 3
         name value                                date      
        <int> <chr>                                <date>    
      1     2 data/BOC_All_ATMImage_(Aug 2021).txt 2021-08-01
      2     5 data/BOC_All_ATMImage_(May 2021).txt 2021-05-01
      3     3 data/BOC_All_ATMImage_(Feb 2021).txt 2021-02-01
      4     1 data/BOC_All_ATMImage_(Aug 2020).txt 2020-08-01
      5     4 data/BOC_All_ATMImage_(Feb_2020).txt 2020-02-01
      6     6 data/BOC_All_ATMImage_(Nov 2019).txt 2019-11-01
      

      还有一些关于你使用的正则表达式的小提示,我认为你不需要让 .* 部分变得懒惰。

      【讨论】:

        【解决方案3】:

        通过从 column_names 解析和排序日期,您可以按时间顺序排列您的 files_names 并从那里处理您的文件

        files_names <- list.files("data/", recursive = TRUE, full.names = TRUE)
        
        column_names <- files_names %>%
          str_extract(., "(?<=\\().*?(?=\\))") %>%
          str_to_lower() %>%
          str_replace(., " ", "_")
        
        
        files_names <- files_names[
        order(readr::parse_date(column_names,"%b_%Y"))]
        files_names
        [1] "data/BOC_All_ATMImage_(Nov 2019).txt"
        [2] "data/BOC_All_ATMImage_(Feb_2020).txt"
        [3] "data/BOC_All_ATMImage_(Aug 2020).txt"
        [4] "data/BOC_All_ATMImage_(Feb 2021).txt"
        [5] "data/BOC_All_ATMImage_(May 2021).txt"
        [6] "data/BOC_All_ATMImage_(Aug 2021).txt"
        

        【讨论】:

          【解决方案4】:

          如果没有 csv 文件,我真的无法运行您的代码,但看起来您已经有了一个小标题列表,并且您已经使用文件名中的片段添加了一个日期列。在这种情况下,您只需要

          data %>% bind_rows() %>% arrange(date)
          

          获取单个 tibble,但根据文件名中的日期对行进行排序。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-04-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-03-07
            • 2019-08-05
            • 2021-12-18
            相关资源
            最近更新 更多