【问题标题】:R convert hourly to daily data up to 0:00 instead of 23:00R将每小时数据转换为每天0:00而不是23:00的数据
【发布时间】:2018-02-20 03:41:56
【问题描述】:

如何在每小时数据中将 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?

【问题讨论】:

    标签: r xts zoo


    【解决方案1】:

    正如此处另一个答案已经指出的那样,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 类型的数据很有用,所以如果你说从分时生成每小时柱,那么查看 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"
    

    【讨论】:

      【解决方案2】:

      我认为这是不可能的,因为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')]
      

      【讨论】:

      • 不是我想要的。我无法控制传入的数据。
      • 然后将分钟数四舍五入。时间 00:00 不是一天的结束,23:59 是根据 POSIXct 标准。
      猜你喜欢
      • 1970-01-01
      • 2016-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-06
      • 2019-11-25
      • 1970-01-01
      相关资源
      最近更新 更多