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

R convert hourly to daily data up to 0:00 instead of 23:00

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

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 吗?

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

These endpoints are aligned in POSIXct time to the zero second of the day at the beginning, and the 59.9999th second of the 59th minute of the 23rd hour of the final day

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

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')]

正如这里的另一个答案已经指出的那样,to.period on days 在相关日期计算时间戳在 00:00:00 和 23:59:59.9999999 之间的数据。因此 23:00:00 被视为您数据中的最后一个时间戳,而 00:00:00 对应于第二天的值 "bin".

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

(更一般地说,to.period 对于生成 OHLCV 类型的数据很有用,因此如果您说从报价生成每小时柱线,查看 [=43= 之间的所有报价是有意义的] 和 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"