【问题标题】:How to get month/year/day of the week from different date formats in R如何从 R 中的不同日期格式获取月/年/星期几
【发布时间】:2018-10-08 01:03:37
【问题描述】:

我有一个数据框,其中包含一个名为“日期”的列。然而,日期格式明显不同。数据类型为字符串。我正在尝试从此数据列创建“月”“年”和“星期几”列。

dataid     date
1         Tue 11/3
2         Wed 11/4 
3          N/A
4         Monday, February 1, 2016
5         Thursday, March 25, 2015 

最好的方法是什么?

【问题讨论】:

    标签: r datetime


    【解决方案1】:

    稳健的方法是使用lubridate::parse_date_time(),但那些没有年份的日期可能会被错误地解析(您可能需要手动编辑它)。

    您可以阅读“help("strptime")”以了解有关如何格式化订单以解析您的日期的更多信息。

    p.s. 2015 年 3 月 25 日是星期三,而不是您的示例数据中的星期四。

    library(dplyr)
    
    library(lubridate)
    
    
    df <- data.table::fread(
    "dataid     date
    1         'Tue 11/3'
    2         'Wed 11/4' 
    3         'N/A'
    4         'Monday, February 1, 2016'
    5         'Thursday, March 25, 2015'
    ",quote="\'")
    
    df.new <- df %>%
      mutate(
        date2 =lubridate::parse_date_time(x =date, orders = c("%a %m/%d", "%A, %B %d, %Y"))
      )
    #> Warning: 1 failed to parse.
    
    
    df.new
    #>   dataid                     date      date2
    #> 1      1                 Tue 11/3 2018-11-03
    #> 2      2                 Wed 11/4 2018-11-04
    #> 3      3                      N/A       <NA>
    #> 4      4 Monday, February 1, 2016 2016-02-01
    #> 5      5 Thursday, March 25, 2015 2015-03-25
    

    reprex package (v0.2.1) 于 2018 年 10 月 8 日创建

    您可以从那里提取年、月、星期几,如下所示:

    df.new %>%
      mutate(
        year = lubridate::year(date2),
        month = lubridate::month(date2),
        day_of_week = weekdays(date2)
      )
    
      #  dataid                     date      date2 year month day_of_week
      #1      1                 Tue 11/3 2018-11-03 2018    11    Saturday
      #2      2                 Wed 11/4 2018-11-04 2018    11      Sunday
      #3      3                      N/A       <NA>   NA    NA        <NA>
      #4      4 Monday, February 1, 2016 2016-02-01 2016     2      Monday
      #5      5 Thursday, March 25, 2015 2015-03-25 2015     3   Wednesday
    

    【讨论】:

      【解决方案2】:

      如果将日期和月份写成字符,则可以在 dplyr::case_when() 调用中使用正则表达式:

      library(dplyr)
      
      df <- df %>%
        mutate(
          day_of_the_week = case_when(
            grepl("mon", date, ignore.case = T) ~ "mon",
            grepl("tue", date, ignore.case = T) ~ "tues",
            grepl("wed", date, ignore.case = T) ~ "wed",
            grepl("thu", date, ignore.case = T) ~ "thurs",
            grepl("fri", date, ignore.case = T) ~ "fri",
            grepl("sat", date, ignore.case = T) ~ "sat",
            grepl("sun", date, ignore.case = T) ~ "sun",
            T ~ NA_character_
          ),
          month = case_when(
            grepl("jan", date, ignore.case = T) ~ "jan",
            grepl("feb", date, ignore.case = T) ~ "feb",
            grepl("mar", date, ignore.case = T) ~ "mar",
            grepl("apr", date, ignore.case = T) ~ "apr",
            grepl("may", date, ignore.case = T) ~ "may",
            grepl("jun", date, ignore.case = T) ~ "jun",
            grepl("jul", date, ignore.case = T) ~ "jul",
            grepl("aug", date, ignore.case = T) ~ "aug",
            grepl("sep", date, ignore.case = T) ~ "sep",
            grepl("oct", date, ignore.case = T) ~ "oct",
            grepl("nov", date, ignore.case = T) ~ "nov",
            grepl("dec", date, ignore.case = T) ~ "dec",
            T ~ NA_character_
          )
        )
      
      #   dataid                     date day_of_the_week month
      # 1      1                 Tue 11/3            tues  <NA>
      # 2      2                 Wed 11/4             wed  <NA>
      # 3      3                     <NA>            <NA>  <NA>
      # 4      4 Monday, February 1, 2016             mon   feb
      # 5      5 Thursday, March 25, 2015           thurs   mar
      

      提取日期/月份数字更难(您可能会以类似的方式对 13 到 31 之间的月份的几天进行操作,但否则无法知道该数字是针对日期还是月份)。

      数据

      df <- read.table(text = "
      dataid     date
      1         'Tue 11/3'
      2         'Wed 11/4'
      3         N/A
      4         'Monday, February 1, 2016'
      5         'Thursday, March 25, 2015'",
                       header = T,
                       stringsAsFactors = F,
                       na.strings = "N/A")
      

      【讨论】:

      • 您可以利用 ignore.case=TRUE 参数到 grepl 来稍微压缩一下。您也不需要perl=TRUE,因为您没有使用任何 Perl 特定的正则表达式。
      • 对于另一种日期格式(周二 11 月 3 日),我使用了相同的功能,但在搜索的方式上稍有欺骗。例如,grepl("11/", date) ~ "nov"。这似乎工作得很好。感谢您的帮助!
      猜你喜欢
      • 1970-01-01
      • 2021-12-16
      • 1970-01-01
      • 2022-01-21
      • 2019-06-30
      • 1970-01-01
      • 2020-01-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多