使用 as.Date 和 tryFormats 来解析不同格式的日期
Use as.Date with tryFormats to parse dates with different formats
我有一个包含两种不同格式("%Y-%m-%d"
和 "%m/%d/%Y"
)的日期的变量:
dput(df)
structure(1:8, .Label = c("2019-04-07", "2019-04-08", "2019-04-09",
"2019-04-10", "7/29/2019", "7/30/2019", "7/31/2019", "8/1/2019"
), class = "factor")
# [1] 2019-04-07 2019-04-08 2019-04-09 2019-04-10 7/29/2019 7/30/2019 7/31/2019 8/1/2019
# 8 Levels: 2019-04-07 2019-04-08 2019-04-09 2019-04-10 7/29/2019 7/30/2019 ... 8/1/2019
我尝试使用 as.Date
和 tryFormats
来解析日期
df <- as.character(df)
d <- as.Date(df, tryFormats = c("%Y-%m-%d", "%m/%d/%Y"))
转换第一个格式结构,然后 returns NA
转换第二个格式结构。如果我 运行 将两种格式分开,它们看起来不错:
t1 <- as.Date(df, format = "%Y-%m-%d")
t2 <- as.Date(df, format = "%m/%d/%Y")
t1
# [1] "2019-04-07" "2019-04-08" "2019-04-09" "2019-04-10" NA
# [6] NA NA NA
t2
# [1] NA NA NA NA "2019-07-29"
# [6] "2019-07-30" "2019-07-31" "2019-08-01"
有什么建议吗?我查看了其他回复,但没有找到任何好的 tryFormats examples/questions 似乎可以解决这个问题。
我们可以使用 anydate
从 anytime
library(anytime)
anydate(df)
如果有任何格式不存在,请使用 addFormats()
添加该格式,然后应用函数
或 lubridate
library(lubridate)
as.Date(parse_date_time(df, c("ymd", "mdy")))
tryFormats
只会 select 一种 给定格式。在您的情况下,您可以单独转换它们,就像您已经完成的那样。
d <- as.Date(df,format="%Y-%m-%d")
d[is.na(d)] <- as.Date(df[is.na(d)],format="%m/%d/%Y")
d
#[1] "2019-04-07" "2019-04-08" "2019-04-09" "2019-04-10" "2019-07-29"
#[6] "2019-07-30" "2019-07-31" "2019-08-01"
对于基本解决方案,您可以按照 answer 中的说明尝试以下操作:
> df
#[1] "2019-04-07" "2019-04-08" "2019-04-09" "2019-04-10" "7/29/2019" "7/30/2019"
#"7/31/2019" "8/1/2019"
fmts <- c("%Y-%m-%d","%m/%d/%Y")
as.Date(apply(outer(df, fmts, as.Date),1,na.omit),'1970-01-01')
#[1] "2019-04-07" "2019-04-08" "2019-04-09" "2019-04-10" "2019-07-29" "2019-07-30" "2019-07-31" "2019-08-01"
我有一个包含两种不同格式("%Y-%m-%d"
和 "%m/%d/%Y"
)的日期的变量:
dput(df)
structure(1:8, .Label = c("2019-04-07", "2019-04-08", "2019-04-09",
"2019-04-10", "7/29/2019", "7/30/2019", "7/31/2019", "8/1/2019"
), class = "factor")
# [1] 2019-04-07 2019-04-08 2019-04-09 2019-04-10 7/29/2019 7/30/2019 7/31/2019 8/1/2019
# 8 Levels: 2019-04-07 2019-04-08 2019-04-09 2019-04-10 7/29/2019 7/30/2019 ... 8/1/2019
我尝试使用 as.Date
和 tryFormats
df <- as.character(df)
d <- as.Date(df, tryFormats = c("%Y-%m-%d", "%m/%d/%Y"))
转换第一个格式结构,然后 returns NA
转换第二个格式结构。如果我 运行 将两种格式分开,它们看起来不错:
t1 <- as.Date(df, format = "%Y-%m-%d")
t2 <- as.Date(df, format = "%m/%d/%Y")
t1
# [1] "2019-04-07" "2019-04-08" "2019-04-09" "2019-04-10" NA
# [6] NA NA NA
t2
# [1] NA NA NA NA "2019-07-29"
# [6] "2019-07-30" "2019-07-31" "2019-08-01"
有什么建议吗?我查看了其他回复,但没有找到任何好的 tryFormats examples/questions 似乎可以解决这个问题。
我们可以使用 anydate
从 anytime
library(anytime)
anydate(df)
如果有任何格式不存在,请使用 addFormats()
添加该格式,然后应用函数
或 lubridate
library(lubridate)
as.Date(parse_date_time(df, c("ymd", "mdy")))
tryFormats
只会 select 一种 给定格式。在您的情况下,您可以单独转换它们,就像您已经完成的那样。
d <- as.Date(df,format="%Y-%m-%d")
d[is.na(d)] <- as.Date(df[is.na(d)],format="%m/%d/%Y")
d
#[1] "2019-04-07" "2019-04-08" "2019-04-09" "2019-04-10" "2019-07-29"
#[6] "2019-07-30" "2019-07-31" "2019-08-01"
对于基本解决方案,您可以按照 answer 中的说明尝试以下操作:
> df
#[1] "2019-04-07" "2019-04-08" "2019-04-09" "2019-04-10" "7/29/2019" "7/30/2019"
#"7/31/2019" "8/1/2019"
fmts <- c("%Y-%m-%d","%m/%d/%Y")
as.Date(apply(outer(df, fmts, as.Date),1,na.omit),'1970-01-01')
#[1] "2019-04-07" "2019-04-08" "2019-04-09" "2019-04-10" "2019-07-29" "2019-07-30" "2019-07-31" "2019-08-01"