首页 > 解决方案 > 通过R中的索引解析多种日期格式

问题描述

我正在尝试根据它们在日期向量中的位置来解析多种日期格式。在某些情况下,数据将其使用的格式从 y/m/d 转换为 y/d/m。这对于像2010/07/03在 lubridate 中指定顺序这样的日期来说很烦人。

这是日期的示例

datevec <- c("2011/07/01", "2011/07/02", "2011/07/03", "2011/02/07" )

日期是这样设置的,所以在某一行之前,日期是一种格式,在另一行之后,日期是另一种格式,所以当我尝试使用它解析它们时,我试图为函数提供一个索引,lubridate而且它只返回 3日期。

lapply(datevec, function(x, i) ifelse( x[i] <4,  parse_date_time(x, "%Y-%m-%d"), parse_date_time(x,"%Y-%d-%m" )) )

标签: rlubridate

解决方案


1)如果我们将问题中的 ifelse 更改为普通的 if,那么问题中的基本思想经过适当的修改即可工作。请注意,它给出了一个列表 L,所以假设我们真的想要一个向量,我们添加最后一行代码。

f <- function(x, i) if (i < 4) 
  parse_date_time(x, "ymd") else parse_date_time(x, "ydm")
L <- Map(f, datevec, seq_along(datevec), USE.NAMES = FALSE)
do.call("c", L)
## [1] "2011-07-01 UTC" "2011-07-02 UTC" "2011-07-03 UTC" "2011-02-07 UTC"

2)在格式部分而不是日期部分使用 ifelse 并使用 as.Date 而不是 parse_date_time:

ix <- seq_along(datevec)
as.Date(datevec, ifelse(ix < 4, "%Y/%m/%d", "%Y/%d/%m"))
## [1] "2011-07-01" "2011-07-02" "2011-07-03" "2011-07-02"

3)使用 ymd 转换前 3 个,使用 ydm 转换其余的,然后连接。

c(ymd(head(datevec, 3)), ydm(tail(datevec, -3)))
## [1] "2011-07-01" "2011-07-02" "2011-07-03" "2011-07-02"

4)或仅使用基础 R:

c(as.Date(head(datevec, 3)), as.Date(tail(datevec, -3), "%Y/%d/%m"))
## [1] "2011-07-01" "2011-07-02" "2011-07-03" "2011-07-02"

5)另一种方法是使用字符串操作转换较晚的日期,使所有日期的格式相同,然后使用 as.Date 或 ymd:

ix <- seq_along(datevec)
swap <- sub("(..)/(..)$", "\\2/\\1", datevec)
as.Date(ifelse(ix < 4, datevec, swap))
## [1] "2011-07-01" "2011-07-02" "2011-07-03" "2011-07-02"

6)上面的代码返回 Date 类,它更适合没有时间的日期,但如果由于某种原因你真的需要 POSIXct 在上面使用 as.POSIXct 或者像这样使用 parse_date_time :

c(parse_date_time(head(datevec, 3), "ymd"), parse_date_time(tail(datevec, -3), "ydm"))
## [1] "2011-07-01 UTC" "2011-07-02 UTC" "2011-07-03 UTC" "2011-07-02 UTC"

推荐阅读