【问题标题】:Creating regular 15-minute time-series from irregular time-series从不规则时间序列创建规则的 15 分钟时间序列
【发布时间】:2012-05-12 12:08:38
【问题描述】:

我在 csv 文件 C:\SampleData.csv 中有一个不规则的时间序列(带有 DateTime 和 RainfallValue):


DateTime,RainInches
1/6/2000 11:59,0
1/6/2000 23:59,0.01
1/7/2000 11:59,0
1/13/2000 23:59,0
1/14/2000 0:00,0
1/14/2000 23:59,0
4/14/2000 3:07,0.01
4/14/2000 3:12,0.03
4/14/2000 3:19,0.01
12/31/2001 22:44,0
12/31/2001 22:59,0.07
12/31/2001 23:14,0
12/31/2001 23:29,0
12/31/2001 23:44,0.01
12/31/2001 23:59,0.01

注意:不规则的时间步长可以是 1 分钟、15 分钟、1 小时等。此外,在所需的 15 分钟间隔内可能会有多个观测值。

我正在尝试创建一个从 2000 年 1 月 1 日到 2001 年 12 月 31 日的常规 15 分钟时间序列,应该如下所示:


2000-01-01 00:15:00 0.00
2000-01-01 00:30:00 0.00
2000-01-01 00:45:00 0.00
...
2001-12-31 23:30:00 0.01
2001-12-31 23:45:00 0.01

注意:时间序列是规则的,间隔为 15 分钟,缺失的数据用 0 填充。如果在 15 分钟的间隔中有多个数据点,则将它们相加。

这是我的代码:


library(zoo)
library(xts)

filename = "C:\\SampleData.csv"
ReadData <- read.zoo(filename, format = "%m/%d/%Y %H:%M", sep=",", tz="UTC", header=TRUE) # read .csv as a ZOO object
RawData <- aggregate(ReadData, index(ReadData), sum) # Merge duplicate time stamps and SUM the corresponding data (CAUTION)
RawDataSeries <- as.xts(RawData,order.by =index(RawData)) #convert to an XTS object

RegularTimes <- seq(as.POSIXct("2000-01-01 00:00:00", tz = "UTC"), as.POSIXct("2001-12-31 23:45:00", tz = "UTC"), by = 60*15)
BlankTimeSeries <- xts((rep(0,length(RegularTimes))),order.by = RegularTimes)

MergedTimeSeries <- merge(RawDataSeries,BlankTimeSeries)
TS_sum15min <- period.apply(MergedTimeSeries,endpoints(MergedTimeSeries, "minutes", 15), sum, na.rm = TRUE )

TS_align15min <- align.time( TS_sum15min [endpoints(TS_sum15min , "minutes", 15)], n=60*15)

问题:输出时间序列TS_align15min: (a) 具有重复的时间戳块 (b) 从 1999 年开始(神秘地),如:

1999-12-31 19:15:00    0
1999-12-31 19:30:00    0
1999-12-31 19:45:00    0
1999-12-31 20:00:00    0
1999-12-31 20:15:00    0
1999-12-31 20:30:00    0

我做错了什么?

感谢您的任何指导!

【问题讨论】:

  • 为我们生成一些可重现的代码,dput() 很有用。还要声明你使用带有 library 或 require 的贡献包。
  • @mdsumner 感谢您的建议。我添加了可重现的示例数据和代码。
  • 不,如果它依赖于我们没有的数据文件,它是不可重现的。请参阅我对具有给定种子的 随机数据 的回答——这使得它可以重现。
  • @DirkEddelbuettel 是的,您的代码使答案可重现。我的数据/代码使问题可重现。谢谢!

标签: r time-series xts zoo


【解决方案1】:

xts 扩展了 zoo,zoo 在其小插曲和文档中有大量示例。
这是一个工作示例。我认为我在过去做得更优雅,但这就是我现在想出的全部:

R> twohours <- ISOdatetime(2012,05,02,9,0,0) + seq(0:7)*15*60
R> twohours
[1] "2012-05-02 09:15:00 GMT" "2012-05-02 09:30:00 GMT" 
[3] "2012-05-02 09:45:00 GMT" "2012-05-02 10:00:00 GMT" 
[5] "2012-05-02 10:15:00 GMT" "2012-05-02 10:30:00 GMT" 
[7] "2012-05-02 10:45:00 GMT" "2012-05-02 11:00:00 GMT"
R> set.seed(42)
R> observation <- xts(1:10, order.by=twohours[1]+cumsum(runif(10)*60*10))
R> observation
                           [,1]
2012-05-02 09:24:08.883625    1
2012-05-02 09:33:31.128874    2
2012-05-02 09:36:22.812594    3
2012-05-02 09:44:41.081170    4
2012-05-02 09:51:06.128481    5
2012-05-02 09:56:17.586051    6
2012-05-02 10:03:39.539040    7
2012-05-02 10:05:00.338998    8
2012-05-02 10:11:34.534372    9
2012-05-02 10:18:37.573243   10

一个两小时的时间网格,一些随机观察使一些单元格为空,一些 填满。

R> to.minutes15(observation)[,4]
                           observation.Close
2012-05-02 09:24:08.883625                 1
2012-05-02 09:44:41.081170                 4
2012-05-02 09:56:17.586051                 6
2012-05-02 10:11:34.534372                 9
2012-05-02 10:18:37.573243                10

这是一个 15 分钟的网格聚合,但不在我们的时间网格上。

R> twoh <- xts(rep(NA,8), order.by=twohours)
R> twoh
                    [,1]
2012-05-02 09:15:00   NA
2012-05-02 09:30:00   NA
2012-05-02 09:45:00   NA
2012-05-02 10:00:00   NA
2012-05-02 10:15:00   NA
2012-05-02 10:30:00   NA
2012-05-02 10:45:00   NA
2012-05-02 11:00:00   NA

R> merge(twoh, observation)
                           twoh observation
2012-05-02 09:15:00.000000   NA          NA
2012-05-02 09:24:08.883625   NA           1
2012-05-02 09:30:00.000000   NA          NA
2012-05-02 09:33:31.128874   NA           2
2012-05-02 09:36:22.812594   NA           3
2012-05-02 09:44:41.081170   NA           4
2012-05-02 09:45:00.000000   NA          NA
2012-05-02 09:51:06.128481   NA           5
2012-05-02 09:56:17.586051   NA           6
2012-05-02 10:00:00.000000   NA          NA
2012-05-02 10:03:39.539040   NA           7
2012-05-02 10:05:00.338998   NA           8
2012-05-02 10:11:34.534372   NA           9
2012-05-02 10:15:00.000000   NA          NA
2012-05-02 10:18:37.573243   NA          10
2012-05-02 10:30:00.000000   NA          NA
2012-05-02 10:45:00.000000   NA          NA
2012-05-02 11:00:00.000000   NA          NA

新的 xts 对象和合并的对象。现在使用na.locf() 进行观察 转发:

R> na.locf(merge(twoh, observation)[,2])
                           observation
2012-05-02 09:15:00.000000          NA
2012-05-02 09:24:08.883625           1
2012-05-02 09:30:00.000000           1
2012-05-02 09:33:31.128874           2
2012-05-02 09:36:22.812594           3
2012-05-02 09:44:41.081170           4
2012-05-02 09:45:00.000000           4
2012-05-02 09:51:06.128481           5
2012-05-02 09:56:17.586051           6
2012-05-02 10:00:00.000000           6
2012-05-02 10:03:39.539040           7
2012-05-02 10:05:00.338998           8
2012-05-02 10:11:34.534372           9
2012-05-02 10:15:00.000000           9
2012-05-02 10:18:37.573243          10
2012-05-02 10:30:00.000000          10
2012-05-02 10:45:00.000000          10
2012-05-02 11:00:00.000000          10

然后我们可以再次合并为时间网格 xts twoh 上的内部连接:

R> merge(twoh, na.locf(merge(twoh, observation)[,2]), join="inner")[,2]
                    observation
2012-05-02 09:15:00          NA
2012-05-02 09:30:00           1
2012-05-02 09:45:00           4
2012-05-02 10:00:00           6
2012-05-02 10:15:00           9
2012-05-02 10:30:00          10
2012-05-02 10:45:00          10
2012-05-02 11:00:00          10
R> 

【讨论】:

  • 谢谢!这看起来不错的样子。让我转换我的代码以遵循这个并返回。我还更改了我的原始帖子以包含可重现的代码和示例数据。
  • 关于优雅:你不需要 twoh 对象。您可以将observation 与“空”xts 对象(xts(,twohours))合并,在其上使用na.locf,然后使用twohours 进行子集化。或者,在一行中:na.locf(merge(xts(,twohours),observation))[twohours]
  • 我也这样做了子集(使用index(twoh),但以错误结束,让我很困惑。很高兴看到我在正确的轨道上......
  • @DirkEddelbuettel 在底部 na.locf(merge(twoh,observation)[,2]) 观察的第二条指令中,如果两个父列都有 NA,我想用 0 填充。我不想重复上一个时间步的观察。这是降雨时间序列。
  • 谢谢!合并 xts 对象上的 rowSums,然后是 period.sum,然后是 align.time 就可以了。再次感谢您回答我关于 stackoverflow 的第一个问题。
【解决方案2】:

这是一个 data.table 解决方案,这可以使用滚动连接巧妙地完成:

library(data.table)
library(xts)

lu <- data.table(index=as.POSIXct("2012-05-02") + (0:7)*15*60)

observation <- xts(1:10,
                   order.by=lu[1,index +cumsum(runif(10)*60*10)])

observation.dt <- as.data.table(observation)
observation.dt[lu,on="index",roll=T]

【讨论】:

    猜你喜欢
    • 2015-03-10
    • 2011-06-16
    • 2021-01-08
    • 2017-03-06
    • 2016-04-07
    • 2011-04-23
    • 2014-09-02
    • 2023-01-20
    相关资源
    最近更新 更多