R每小时转换为每日数据,最多为0:00而不是23:00

时间:2018-02-20 03:41:57

标签: r xts zoo

如何在每小时数据中将0:00设置为每天结束而不是23:00?在使用period.applyto.period作为返回日期结束于23:00时,我遇到了这种困难。这是一个例子:

x1 = xts(seq(as.POSIXct("2018-02-01 00:00:00"), as.POSIXct("2018-02-05 23:00:00"), by="hour"), x = rnorm(120))

以下功能显示期间于23:00结束

to.period(x1, OHLC = FALSE, drop.date = FALSE, period = "days")
x1[endpoints(x1, 'days')]

因此,当我将每小时数据汇总到每日时,是否有人知道如何在0:00设置结束日期?

2 个答案:

答案 0 :(得分:3)

正如此处的另一个答案已经指出的那样,to.period天计算时间戳在00:00:00和23:59:59.9999999之间的数据。所以23:00:00被视为数据中的最后一个时间戳,00:00:00对应于第二天的值" bin"。

您可以做的是将所有时间戳恢复1小时,使用to.period从小时点获取每日数据点,然后使用align.time正确对齐时间戳。

(更一般地说,to.period对于生成OHLCV类型数据非常有用,因此,如果您说从刻度线生成说小时栏,那么查看23:00之间的所有刻度是有意义的:创建栏中的00和23:59:59.99999。然后00:00:00到00:59:59.9999 ....将形成下一个小时栏等等。)

以下是一个例子:

> tail(x1["2018-02-01"])
# [,1]
# 2018-02-01 18:00:00 -1.2760349
# 2018-02-01 19:00:00 -0.1496041
# 2018-02-01 20:00:00 -0.5989614
# 2018-02-01 21:00:00 -0.9691905
# 2018-02-01 22:00:00 -0.2519618
# 2018-02-01 23:00:00 -1.6081656

> head(x1["2018-02-02"])
# [,1]
# 2018-02-02 00:00:00 -0.3373271
# 2018-02-02 01:00:00  0.8312698
# 2018-02-02 02:00:00  0.9321747
# 2018-02-02 03:00:00  0.6719425
# 2018-02-02 04:00:00 -0.5597391
# 2018-02-02 05:00:00 -0.9810128

> head(x1["2018-02-03"])
# [,1]
# 2018-02-03 00:00:00  2.3746424
# 2018-02-03 01:00:00  0.8536594
# 2018-02-03 02:00:00 -0.2467268
# 2018-02-03 03:00:00 -0.1316978
# 2018-02-03 04:00:00  0.3079848
# 2018-02-03 05:00:00  0.2445634

x2 <- x1
.index(x2) <- .index(x1) - 3600

> tail(x2["2018-02-01"])
# [,1]
# 2018-02-01 18:00:00 -0.1496041
# 2018-02-01 19:00:00 -0.5989614
# 2018-02-01 20:00:00 -0.9691905
# 2018-02-01 21:00:00 -0.2519618
# 2018-02-01 22:00:00 -1.6081656
# 2018-02-01 23:00:00 -0.3373271

x.d2 <- to.period(x2, OHLC = FALSE, drop.date = FALSE, period = "days")

> x.d2
# [,1]
# 2018-01-31 23:00:00  0.12516594
# 2018-02-01 23:00:00 -0.33732710
# 2018-02-02 23:00:00  2.37464235
# 2018-02-03 23:00:00  0.51797747
# 2018-02-04 23:00:00  0.08955208
# 2018-02-05 22:00:00  0.33067734

x.d2 <- align.time(x.d2, n = 86400)

> x.d2
# [,1]
# 2018-02-01  0.12516594
# 2018-02-02 -0.33732710
# 2018-02-03  2.37464235
# 2018-02-04  0.51797747
# 2018-02-05  0.08955208
# 2018-02-06  0.33067734

想要说服自己?尝试这样的事情:

x3 <- rbind(x1, xts(x = matrix(c(1,2), nrow = 2), order.by = as.POSIXct(c("2018-02-01 23:59:59.999", "2018-02-02 00:00:00"))))

x3["2018-02-01 23/2018-02-02 01"]
# [,1]
# 2018-02-01 23:00:00.000 -1.6081656
# 2018-02-01 23:59:59.999  1.0000000
# 2018-02-02 00:00:00.000 -0.3373271
# 2018-02-02 00:00:00.000  2.0000000
# 2018-02-02 01:00:00.000  0.8312698
x3.d <- to.period(x3, OHLC = FALSE, drop.date = FALSE, period = "days")


> x3.d <- align.time(x3.d, 86400)
> x3.d
[,1]
2018-02-02  1.00000000
2018-02-03 -0.09832625
2018-02-04 -0.65075506
2018-02-05 -0.09423664
2018-02-06  0.33067734

请注意,00:00:00的2的值不是2018-02-02(00:00:00)当天的最后一次观察,该观察从2018-02-01 00:00开始: 00至2018-02-01 23:59:59.9999。

当然,如果您希望每日时间戳是当天的开始,而不是当天的结束,那将是2018-02-01作为第一行的开头,在x3.d在上面,你可以把这一天换回来。当您的数据不涉及周末日期时,您可以在大多数时区相对安全地执行此操作:

index(x3.d) = index(x3.d) - 86400

我说的比较安全,因为在时区有时间变化的情况下会出现角落情况。例如节省日光要小心。简单地减去-86400可能是一个问题,从星期日到星期六在发生日间照明的时区:

  #e.g. bad:  day light savings occurs on this weekend for US EST
  z <- xts(x = 9, order.by = as.POSIXct("2018-03-12", tz = "America/New_York"))
  > index(z) - 86400
  [1] "2018-03-10 23:00:00 EST"

即。当你真正想要午夜时间戳(00:00:00)时,时间戳会关闭一个小时。

你可以使用更安全的东西解决这个问题:

  library(lubridate)

  # right
  > index(z) - days(1)
  [1] "2018-03-11 EST"

答案 1 :(得分:1)

我不认为这是可能的,因为00:00是一天的开始。从手册:

  

这些终点在POSIXct时间内与开始时的第二天零点以及最后一天第23小时第59分钟的59.9999秒对齐

我认为这里的解决方案是使用分钟而不是几小时。使用您的示例:

x1 = xts(seq(as.POSIXct("2018-02-01 00:00:00"), as.POSIXct("2018-02-05 23:59:99"), by="min"), x = rnorm(7200))
to.period(x1, OHLC = FALSE, drop.date = FALSE, period = "day")
x1[endpoints(x1, 'day')]