R从日期开始下降小时,分钟和秒

时间:2017-01-25 01:16:54

标签: r datetime time xts

将数据帧转换为xts时,我意识到格式化程序出了问题。这是一个示例数据框:

effective_date         price
"1990-01-01"  "100"
"1990-01-02 00:05:00"  "200"

这是我使用的包的示例输出。

将此转换为xts是直截了当的

xts(df["price"], order_by=as.POSIXct(df["effective_date"], format="%Y-%m-%d %H:%M:%S")

然而,这出错了,说NAs不能在行名称中,结果是:

<NA>       100
1990-01-02 00:05:00  200

显然xts无法弄清楚如何处理那里的奇怪日期(午夜)并且它不会强迫它。

如果我将tz="UTC"添加到as.POSIXct,它就无法运作。此外,as.POSIXlt也不会改变任何内容。

我可以做些什么来强制将午夜日期强制为正确的格式?

4 个答案:

答案 0 :(得分:8)

两个问题:

1)您不能单独使用给定格式解析日期为POSIXct:

R> as.POSIXct(c("2017-01-02", "2017-01-03 04:05:06"), format="%Y-%m-%d %H:%M:%S")
[1] NA                        "2017-01-03 04:05:06 CST"
R>

2)但是,您可以使用anytime()函数来执行此操作:

R> anytime::anytime(c("2017-01-02", "2017-01-03 04:05:06"))
[1] "2017-01-02 00:00:00 CST" "2017-01-03 04:05:06 CST"
R> 

获得POSIXct后,xts就很容易了。

另请注意,您有拼写错误:您需要在列指示符之前使用逗号:df[, "price"]

编辑:对@ 42关于Gabor的(精细)解决方案“主导”这个问题的评论有点厌倦,所以这里是最小的基准:

R> library(microbenchmark)
R> v <- c("2017-01-02", "2017-01-03 04:05:06")
R> library(anytime)
R> print(microbenchmark(anytime(v), do.call("c", lapply(v, as.POSIXct))), digits=3)
Unit: microseconds
                                expr   min    lq  mean median    uq   max neval cld
                          anytime(v)  33.6  36.8  42.1   45.6  46.6  80.7   100  a 
 do.call("c", lapply(v, as.POSIXct)) 571.5 579.1 586.4  586.8 589.5 695.7   100   b
R> 

所以总之“不是真的”。它只使用R Base,这是一个加号,它是a)更难阅读和理解,b)更有限,因为它处理正好一种格式(ISO风格)和c)它是约慢13倍

答案 1 :(得分:7)

1)要获取"POSIXct"日期时间向量,请尝试将每个日期时间分别转换为"POSIXct",然后将它们连接在一起:

do.call("c", lapply(df$effective_date, as.POSIXct))

2)另一个基本解决方案更短,速度也更快,以下是as.POSIXct在最后忽略垃圾的事实。

as.POSIXct(paste(df$effective, "00:00:00"))

答案 2 :(得分:3)

大多数lubridate解析函数都有一个truncated参数,该参数带有一个数字,表示可以从末尾丢失的元素数量。缺少的元素将被零替换。

手头的数据示例:

lubridate::ymd_hms(c("2017-01-02", "2017-01-03 04:05:06"), truncated = 3)
## [1] "2017-01-02 00:00:00 UTC" "2017-01-03 04:05:06 UTC"

答案 3 :(得分:1)

假设您需要时间戳,请使用以下内容进行预处理:

temp <- c("1990-01-01", "1990-01-02 00:05:00")

# match a date string at the end of string (indicated by $). Replace
# with the full string (indicated by \\1 and 00:00:00
temp2 <- gsub("(\\d{4}\\-\\d{2}\\-\\d{2}$)", "\\1 00:00:00", temp)

# [1] "1990-01-01 00:00:00" "1990-01-02 00:05:00"