通过R中的索引解析多种日期格式

时间:2021-02-20 22:43:37

标签: r lubridate

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

这是一个日期示例

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

日期是这样设置的,所以在某一行之前日期是一种格式,在另一行之后日期是另一种格式,所以我试图为函数提供一个索引 当我尝试使用 this plus 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" )) )

1 个答案:

答案 0 :(得分:2)

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"