【问题标题】:R_Extracting time series based on the hoursR_根据小时数提取时间序列
【发布时间】:2014-07-01 03:18:00
【问题描述】:

我有一个较长的时间序列“obs”,时间步长为 1 小时 (class="zoo")。有一些缺失值已被删除,因此时间步长不再一致

> head(obs)
               time obs   
2009-12-22 01:00:00 23.708
2009-12-22 02:00:00 23.708
2009-12-22 03:00:00 23.708
2009-12-22 04:00:00 23.708
2009-12-22 06:00:00 23.708
2009-12-22 07:00:00 23.708

> tail(obs)
               time obs 
2013-09-22 21:00:00 45.031
2013-09-22 22:00:00 45.031
2013-09-22 23:00:00 41.589
2013-09-23 00:00:00 28.987
2013-09-23 01:00:00 22.238
2013-09-23 02:00:00 20.533

现在,我想从这个时间序列创建多个时间序列,从每个小时开始,时间步长为 12 小时。所以总共应该有12个时间序列。下面给出了预期的输出之一(从 01:00:00 开始)

               time obs
2009-12-22 01:00:00 23.708
2009-12-22 13:00:00 23.708
2009-12-23 01:00:00 23.708
2009-12-23 13:00:00 24.136
2009-12-24 01:00:00 23.708
2009-12-24 13:00:00 23.708
....

像这样,我需要创建其他时间序列(从 02:00:00、03:00:00 等开始),时间步长为 12 小时。如果时间步长是一致的,我可以转换每 12 小时的行数据,然后从每一列中提取它会容易得多。但现在不可能了。我该怎么做?我已经在使用 xts 包了。但我找不到办法。

【问题讨论】:

  • 任何答案对您有帮助吗?

标签: r time-series


【解决方案1】:

xts 是正确的包。你感兴趣的是函数

[.xts(提取 xts 对象的子集)

例如:

obs["T01:00/T01:59"]

将返回“T”时间在 01:00 和 01:59 之间的所有观察结果。

你只需要矢量化,然后把所有的东西放在一起你就可以得到类似这样的东西:

my_func <- function(i, obs){
   if(i > 9){ 
      hours <- paste("T", i, ":00/T", i, ":59", sep = "") 
   }else{
      hours <- paste("T0", i, ":00/T0", i, ":59", sep = "") 
   }   
   hours.12 <- paste("T", i + 12, ":00/T", i + 12, ":59", sep = "") 
   #
   obs.subset <- rbind(obs[hours], obs[hours.12])
}
# get a list of 12 subsets as requested
obs.subsetted <- lapply(0:11, my_func, obs)

【讨论】:

  • 谢谢@luis_js。这也解决了问题。但是请检查我的答案,这更直接。
【解决方案2】:

这是使用data.table 和lubridate 的解决方案。

整个代码 sn-p 在我的笔记本电脑上用时不到 0.01 秒。

# Load packages
library(lubridate)
library(data.table)

# Set up data
time <- seq(ymd_hms("2009-12-22 01:00:00"), ymd_hms("2013-09-23 02:00:00"), by="1 hour")
obs <- abs(rnorm(length(time)))
dt <- data.table(time, obs)

# Set up a list where all 12 output data tables are stored
l <- vector(12, mode="list")

# Split original data
for (i in 0:11){
  l[[i+1]] <- dt[seq(from=i+1, to=nrow(dt), by=12)]
}

输出数据如下所示:

> l
[[1]]
                     time        obs
   1: 2009-12-22 01:00:00 1.14244266
   2: 2009-12-22 13:00:00 1.13037973
   3: 2009-12-23 01:00:00 0.18268572
   4: 2009-12-23 13:00:00 0.56539405
   5: 2009-12-24 01:00:00 0.06480253
  ---                               
2739: 2013-09-21 01:00:00 1.06874026
2740: 2013-09-21 13:00:00 0.04367871
2741: 2013-09-22 01:00:00 0.43790836
2742: 2013-09-22 13:00:00 1.41966787
2743: 2013-09-23 01:00:00 0.68687465

[[2]]
                     time       obs
   1: 2009-12-22 02:00:00 1.6789682
   2: 2009-12-22 14:00:00 0.1321111
   3: 2009-12-23 02:00:00 2.5129179
   4: 2009-12-23 14:00:00 0.9818898
   5: 2009-12-24 02:00:00 0.6617939
  ---                              
2739: 2013-09-21 02:00:00 0.6028943
2740: 2013-09-21 14:00:00 0.4571396
2741: 2013-09-22 02:00:00 0.7017483
2742: 2013-09-22 14:00:00 0.1206088
2743: 2013-09-23 02:00:00 0.3864518

[[3]]
                     time        obs
   1: 2009-12-22 03:00:00 2.14461926
   2: 2009-12-22 15:00:00 0.68896644
   3: 2009-12-23 03:00:00 0.19332982
   4: 2009-12-23 15:00:00 1.09463684
   5: 2009-12-24 03:00:00 0.60102308
  ---                               
2738: 2013-09-20 15:00:00 0.36922591
2739: 2013-09-21 03:00:00 0.89973806
2740: 2013-09-21 15:00:00 0.02761852
2741: 2013-09-22 03:00:00 0.17313669
2742: 2013-09-22 15:00:00 0.61018630

[[4]]
...

【讨论】:

  • 谢谢@majom。这仅在时间步长一致时才有效。但正如我已经提到的,由于缺少数据,时间步长并不一致。否则我可以将 12 小时的数据转换为行,然后从每一列中提取。
【解决方案3】:

找了这么久,从xts包里找到了这个直截了当的方法

 obs[.indexhour(x) %in% c(t1,t2)]

这会提取每天对t1 和t2 小时的所有观察。有关更多详细信息,请尝试xts 包中的?indexClass

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    • 2023-01-27
    • 2019-08-02
    • 1970-01-01
    • 1970-01-01
    • 2015-07-01
    相关资源
    最近更新 更多