用日期替换可变结构文本

Replacement of variable structure text with a date

我有以下数据:

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 个案例中不起作用(可以理解)。

你可以试试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() 调用。

基于包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"))

从字符串开头删除“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"

我们可以使用 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