【问题标题】:Replacement of variable structure text with a date用日期替换可变结构文本
【发布时间】:2020-07-11 09:12:34
【问题描述】:

我有以下数据:

df <- data.frame(dt.str = c("X2019.12.31.23.59.5", "X2020.01.31.23.59.59", "X2020.02.29.23.59.59", "X30.04.2020.23.59", "X30.04.2020.23.59", "X30.06.2020.23.59"), value = c(4, 3.42,2.96,7.26,3.35,2.986))

我想将 dt.str 转换为日期。

df <- df %>% mutate (dt.str.2 = as.Date(str_extract(dt.str, "[^X]+$"), format= "%Y.%m.%d.%H.%M"))

但是,此解决方案在最后 3 种情况下不起作用(可以理解)。

【问题讨论】:

    标签: r dplyr lubridate


    【解决方案1】:

    基于包lubridate的解决方案:

    library(lubridate)
    df$dt.str.2 <- format(parse_date_time(sub("^X(.{10}).*$","\\1",df$dt.str), 
                                          orders = c("%Y.%m.%d", "%d.%m.%Y")), "%Y.%m.%d")
    
    df
                    dt.str value   dt.str.2
    1  X2019.12.31.23.59.5 4.000 2019.12.31
    2 X2020.01.31.23.59.59 3.420 2020.01.31
    3 X2020.02.29.23.59.59 2.960 2020.02.29
    4    X30.04.2020.23.59 7.260 2020.04.30
    5    X30.04.2020.23.59 3.350 2020.04.30
    6    X30.06.2020.23.59 2.986 2020.06.30
    

    dplyr:

    library(lubridate)
    library(dplyr)
    df <- df %>% 
      mutate (dt.str.2 = format(parse_date_time(sub("^X(.{10}).*$","\\1",dt.str), 
                                                orders = c("%Y.%m.%d", "%d.%m.%Y")), "%Y.%m.%d"))
    

    【讨论】:

      【解决方案2】:

      从字符串开头删除“X”后,您可以使用lubridate 中的parse_date_time

      library(lubridate)
      as.Date(parse_date_time(sub('^X', '', df$dt.str), c('YmdHMS', 'dmyHM')))
      #[1] "2019-12-31" "2020-01-31" "2020-02-29" "2020-04-30" "2020-04-30" "2020-06-30"
      

      【讨论】:

      • 优雅易懂
      【解决方案3】:

      你可以试试if_else:

      df = df %>% mutate (dt.str.2 = if_else(
      nchar(str_extract(string =df$dt.str,pattern = '(?<=X)\\d*(?=.)'))==4,
      true = as.Date(str_extract(dt.str, "[^X]+$"), format= "%Y.%m.%d.%H.%M.%S"),
      false =as.Date(str_extract(dt.str, "[^X]+$"), format= "%d.%m.%Y.%H.%M")))
      
                      dt.str value   dt.str.2
      1  X2019.12.31.23.59.5 4.000 2019-12-31
      2 X2020.01.31.23.59.59 3.420 2020-01-31
      3 X2020.02.29.23.59.59 2.960 2020-02-29
      4    X30.04.2020.23.59 7.260 2020-04-30
      5    X30.04.2020.23.59 3.350 2020-04-30
      6    X30.06.2020.23.59 2.986 2020-06-30
      

      如果数据中有两个以上的日期模式,您可以继续在 false 参数中附加 if_else() 调用。

      【讨论】:

        【解决方案4】:

        我们可以从anytime使用anytime

        library(lubridate)
        library(anytime)
        library(dplyr)
        library(stringr)
        addFormats("%d.%m.%Y.%H.%M")
        df %>% 
            mutate(dt.str.2 = as_date(anytime(str_remove(dt.str, "^X"))))
        #                dt.str value   dt.str.2
        #1  X2019.12.31.23.59.5 4.000 2019-12-31
        #2 X2020.01.31.23.59.59 3.420 2020-01-31
        #3 X2020.02.29.23.59.59 2.960 2020-02-29
        #4    X30.04.2020.23.59 7.260 2020-04-30
        #5    X30.04.2020.23.59 3.350 2020-04-30
        #6    X30.06.2020.23.59 2.986 2020-06-30
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-24
          • 2015-03-17
          • 1970-01-01
          • 2021-11-20
          相关资源
          最近更新 更多