R_根据小时数提取时间序列

时间:2014-05-13 12:34:45

标签: r time-series

我有一个很长的时间序列'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包了。但我找不到办法。

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

以下是使用data.tablelubridate的解决方案。

我的笔记本电脑上的整个代码段不到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]]
...

答案 2 :(得分:1)

经过长时间的搜索,我从xts

找到了这个直接的方法
 obs[.indexhour(x) %in% c(t1,t2)]

这会提取每天t1t2小时的所有观察结果。有关详情,请参阅?indexClass

中的xts