【问题标题】:Editing Index After Aggregation Using XTS in R在 R 中使用 XTS 聚合后编辑索引
【发布时间】:2015-10-27 11:44:00
【问题描述】:

我正在使用 xts 包在 R 中创建示例时间序列。我创建了一个日期范围,以分钟分隔,为每个日期创建示例数据,然后最后聚合小时,汇总数据。这有效,除了一个问题。

完成聚合后,索引不会显示每小时的每个数据,而是显示第 59 分钟的数据。我需要在小时显示索引以合并关注点。以下是我的代码:

#xts simple example code

BD <- chron("01/01/2015", "00:00:00") # Setting begin date.
ED <- chron("02/01/2015", "23:59:00") # Setting end date.
DS <- seq(BD, ED, by = times("00:01:00")) # Creating a sequence of dates seperated by a minute.

data <- runif(length(DS), 0, 100) # Generating random numerical data the length of the date sequence.

x <- xts(data, DS) # Creates an xts object indexed by the dates of "DS" with data from "data".
colnames(x) <- "Data" # Just renaiming the data column in the xts object.

x.agg <- period.apply(x, endpoints(x, "hours"), sum) # Aggregating by hour

我试过这个方法:

index(x.agg) <- index(x.agg) - (1/24/60) * 59

但它在尾部给了我这样的回应:

> index(x.agg) <- index(x.agg) - (1/24/60) * 59
> tail(index(x.agg))
[1] (02/01/15 13:00:00) (02/01/15 14:00:00) (02/01/15 15:00:00) (02/01/15        
16:00:00) (02/01/15 17:00:00)
[6] (02/01/15 18:00:00)

上面的整个想法是简单地减去 59 分钟来得到它,但它似乎不起作用。我也尝试过截断和舍入,但它们也给了我奇怪的结果。任何想法将不胜感激!

【问题讨论】:

    标签: r time-series aggregation xts


    【解决方案1】:

    您要求做的事情可能非常危险。您说您希望将聚合数据与小时的开始对齐,以便您可以将其与另一个系列合并。您可以通过更改观察时间戳来引入偏差。

    索引确实显示每小时的每个数据。请注意,您使用了一个名为endpoints 的函数,因此该小时的数据位于每个小时的end。如果您想在一小时开始时聚合,请使用startpoints function。在这种情况下,该答案中的函数似乎有一个微妙的错误。这是一个补丁版本:

    startpoints <- function (x, on = "months", k = 1) {
      c(0, head(endpoints(x, on, k)[-1] + 1, -1))
    }
    

    请注意,如果您使用 endpointsstartpoints,数据列的不同之处。如果您只是更改了 endpoints 版本的输出索引,这就是您可能引入的偏差示例。

    > head(x.agg <- period.apply(x, startpoints(x, "hours"), sum))
                            Data
    (01/01/15 07:00:00) 3249.408
    (01/01/15 08:00:00) 2967.049
    (01/01/15 09:00:00) 3110.734
    (01/01/15 10:00:00) 2977.106
    (01/01/15 11:00:00) 3046.607
    (01/01/15 12:00:00) 3417.428
    > head(x.agg <- period.apply(x, endpoints(x, "hours"), sum))
                            Data
    (01/01/15 06:59:00) 3236.172
    (01/01/15 07:59:00) 2893.148
    (01/01/15 08:59:00) 3100.842
    (01/01/15 09:59:00) 2996.260
    (01/01/15 10:59:00) 3088.869
    (01/01/15 11:59:00) 3353.841
    

    另一种可能的解决方案是在使用endpointsperiod.apply 调用的输出上使用align.timealign.time(x, 3600) 会将索引四舍五入到下一小时。

    head(x.agg <- align.time(period.apply(x, endpoints(x, "hours"), sum), 3600))
    (01/01/15 07:00:00) 3236.172
    (01/01/15 08:00:00) 2893.148
    (01/01/15 09:00:00) 3100.842
    (01/01/15 10:00:00) 2996.260
    (01/01/15 11:00:00) 3088.869
    (01/01/15 12:00:00) 3353.841
    

    【讨论】:

    • 这与我最终想要的非常接近。但是,我用提供的 startpoints 函数替换运行它,唯一的问题是第一个聚合日期表示为:“01/01/15 01:00:00”,而我希望它表示为:“01/ 01/15 00:00:00”表示这是日期在该小时内的所有数据点的聚合。我尝试用负 59 代替 + 1,但它在数据末尾产生了同样的问题。可能我误解了端点如何解析“小时”。
    • @giraffehere:使用我链接到的问题中的startpoints 函数(不是我的“修补”版本),然后将调用更改为:period.apply(x, c(0,startpoints(x, "hours")), sum)
    • 出于某种奇怪的原因,时间“01/01/15 00:00:00”的聚合仍然只将“01/01/15 00:00:00”的分钟计入总和(所以它是一个非常小的数量),其余的似乎进入“01/01/15 01:00:00”小时(数量要大得多),所以我一定有什么误解。但无论如何,你对此非常有帮助,我不想再占用你的时间了。我相信我能在适当的时候弄清楚或找到替代方案。太感谢了! :)
    • @giraffehere:我认为你的误解是你所要求的可能非常危险,所以我没有告诉你怎么做。您要求通过创建一个数据结构来“聚合”时间序列数据,该数据结构在每个时间戳都包含来自未来的数据。请参阅我的编辑以了解另一种可能的解决方案。
    • 虽然我确实明白你的意思,但我无法理解为什么要在(包括)时间(例如)00:00:00 和 00:59 之间进行聚合: 00 并将该聚合表示为 00:00:00 的时间太糟糕了。正如你所说,我确实希望时间戳代表未来的数据:“这是在 00:00:00 小时内发生的数据点的聚合”。 period.apply(x, endpoints(x, "hours"), sum) 确实给了我想要的聚合,但没有正确的时间戳。
    猜你喜欢
    • 2016-06-14
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 2021-08-07
    • 2011-04-14
    • 1970-01-01
    • 2020-03-22
    • 2011-05-16
    相关资源
    最近更新 更多