将数据帧转换为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
也不会改变任何内容。
我可以做些什么来强制将午夜日期强制为正确的格式?
答案 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"