【问题标题】:How do I extract / subset day+0 to day+1 index times from minutely data via xts in R?如何通过 R 中的 xts 从分钟数据中提取/子集 day+0 到 day+1 索引时间?
【发布时间】:2012-03-28 13:33:22
【问题描述】:

我正在尝试在 XTS 中生成跨日、可子设置的时间序列。

例如,假设我有一个在 10 年内每天 24 小时生成的分钟时间序列 (mts)。例如,我想提取时间序列中每个“天”的每个(t+0 上午 08:30 到 t+1 13:30)时段。

使用 xts 在同一天的 08:30 到 16:00 执行此操作是微不足道的,并且在 StackExchange 上得到了很好的解决:即mts["T08:29:59/T16:01:00"]

但是我如何编写等价的时间序列的端点作为子集的时间是第二天发生的时间?

任何想法都非常感谢。

【问题讨论】:

  • 上午 8:30 至下午 1:30第二天,对于每一天,将是第一天 8:30 到最后一天 13:30 之间的所有数据。如果你只是想在 2012 年 1 月 1 日开始,那就是mts["2012-01-01 08:30/2012-01-02 13:30"]
  • 我希望在 10 年系列中的所有日子的特定子期间都这样做。抱歉,如果我在最初的问题中没有说清楚
  • 对,但由于子时段重叠,您将获得第一天 8:30 到最后一天 13:30 之间的所有数据。

标签: r time-series xts


【解决方案1】:

这将创建一个列表,其中列表的每个元素都是一个 xts 对象,从 8:30 开始,到第二天的 13:30 结束。

D <- split(mts, "days")
mts.days <- lapply(seq_along(D) - 1, function(i) {
  if (i > 0) rbind(D[[i]]["T08:30/T23:59:59"], D[[i + 1]]["T00:00:00/T13:30:00"])
})

编辑: 可以通过在列表中添加名称来扩展上述内容:

names(mts.days) <- as.Date(sapply(D, function(x) as.Date(start(x))))

然后,您可以参考 2012 年 1 月 30 日上午 8:30 至下午 1:30 的数据。在2012-01-31这样的

mts.days[["2012-01-30"]]

或者,如果你只打算抽出“一天”,你可以做这样的事情(遵循相同的基本逻辑)

PullDay <- function(Date="2012-01-30", t0="08:30", t1="13:30", mts=mts) {
  string1 <- paste(Date, " ", t0, "/", Date, " 23:59:59", sep="")
  string2 <- paste(as.Date(Date) + 1, " 00:00:00/", as.Date(Date) + 1, " ", t1, sep="")
  rbind(mts[string1], mts[string2])
}

然后,PullDay("2012-01-30") 将为您提供 2012-01-30 08:30/2012-01-31 13:30 的数据子集。

Edit2:简化为

PullDay <- function(Date="2012-01-30", t0="08:30", t1="13:30", mts=mts) {
  mts[paste(Date, " ", t0, "/", as.Date(Date) + 1, " ", t1, sep="")]
}

这让我相信我可能仍然不明白你想要什么......

【讨论】:

  • 这是一个有趣的解决方案,并且巧妙地组合在一起,但列表格式不适用于我想做的分析。就像在xts 中一样,我想最终得到该子集的连续时间序列。非常感谢您的尝试;非常感谢。
  • 我已经在 2 cmets 中提供了解决方案。如果您认为您想要的与根本不对数据进行子集化不同(除了第一天和最后一天),那么请解释您想要什么。您想要从上午 8:30 到下午 1:30 的重复行名吗?每天?
  • 恐怕我不明白你在另外两个 cmets 中暗示的答案。我假设我没有正确传达一些东西。时间序列不仅仅是从 08:30 t0 到 13:30 t+1 的每一分钟。这是一个 24 小时的时间序列。我只是想在两天内抽出一个定义的子时段。从今天的 09:00:00 到明天的 07:00:00 也很容易。
  • 很抱歉,我说得不够清楚。我只是不明白你说“早上 8:30 到第二天下午 1:30,对​​于每一天,将是第一天 8:30 到第二天 13:30 之间的所有数据。最后一天。”和“但由于子时段重叠,您将获得第一天 8:30 和最后一天 13:30 之间的所有数据。”因为这似乎(在我看来)解决了一个稍微不同的问题。
  • 啊。行。令人困惑的是mts["T08:30/T13:30"] 将删除不在 8:30 到 1:30 之间的所有日期的所有数据。它运行几天。如果您想要每天 29 小时的子集,您并没有减少数据点的数量。现在我将编辑答案,因为我知道您不想每天都进行子集化。
【解决方案2】:

我自己也在寻找这个问题的答案。 GSee的回答是完美的。但由于没有提供数据,我自己编造了。在此过程中稍微调整了 GSee 的代码。对于 OP,请选择 GSee 的答案,因为它回答了您的问题。如果有人对此问题感兴趣(包括我未来的自己),下面的代码供参考:

创建一个在 3 天内从 8:30 开始到 13:30 结束的 xts 对象:

ticks <- 24*60*10
mts <- xts( runif(ticks,0,1)
              , order.by = seq( as.POSIXct("2013-01-01 08:30:00")
                                , as.POSIXct("2013-01-03 13:30:00")
                                , length = ticks
                           ) 
         )


D <- split(mts, "days")
D[1]; D[2]; D[3];

GSee 从 xts 对象中提取数据的函数:

PullDay <- function(x, d0 = "2013-01-01", d1 = "2013-01-03", t0 = "08:30", t1 = "13:30") 
 {
   x[paste0(d0, " ", t0, "/", d1, " ", t1)]
 }

从 2013 年 1 月 2 日上午 8:30 到下午 1:30 提取数据。在同一天,做:

PullDay(mts, d0="2013-01-02", d1="2013-01-02")

要指定准确的范围,请执行以下操作:

PullDay(mts, d0="2013-01-02", d1="2013-01-02", t0="09:00", t1="09:01")

如果有人发现错误,您有权编辑和更正。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-05-18
  • 2016-11-07
  • 2014-07-16
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 2013-07-25
  • 1970-01-01
相关资源
最近更新 更多