【问题标题】:Aggregating a timestamped zoo object by clock time (i.e. not solely by time in the zoo object)按时钟时间聚合一个带时间戳的动物园对象(即不仅仅按动物园对象中的时间)
【发布时间】:2012-02-27 11:26:40
【问题描述】:

我有一个动物园对象,它由一个带时间戳的(到第二个)时间序列组成。时间序列是不规则的,因为值之间的时间间隔不是规则间隔的。

我想将不规则间隔的时间序列对象转换为规则间隔的对象,其中值之间的时间间隔是一个常数 - 比如 15 分钟,并且是“真实世界”的时钟时间。

一些示例数据可能有助于进一步说明

# Sample data
2011-05-05 09:30:04 101.32
2011-05-05 09:30:14 100.09
2011-05-05 09:30:19 99.89
2011-05-05 09:30:35 89.66
2011-05-05 09:30:45 95.16
2011-05-05 09:31:12 100.28
2011-05-05 09:31:50 100.28
2011-05-05 09:32:10 98.28

我想在每个指定的时间段(例如 30 秒时间段)汇总它们(使用我的自定义函数),以便输出如下表所示。

关键是我想从我的第一次观察时间开始每 30 秒按时钟时间而不是 30 秒聚合一次。自然,第一个时间桶将是我在要聚合的数据中记录观察(即行)的第一个时间桶。

2011-05-05 09:30:00   101.32
2011-05-05 09:30:30   89.66
2011-05-05 09:31:00   100.28

在给出的示例中,我的自定义聚合函数只是返回要聚合的“选定行”的“集合”中的第一个值。

【问题讨论】:

    标签: r aggregation zoo


    【解决方案1】:

    读入数据,然后按分钟聚合:

    Lines <- "2011-05-05 09:30:04 101.32
    2011-05-05 09:30:14 100.09
    2011-05-05 09:30:19 99.89
    2011-05-05 09:30:35 89.66
    2011-05-05 09:30:45 95.16
    2011-05-05 09:31:12 100.28
    2011-05-05 09:31:50 100.28
    2011-05-05 09:32:10 98.28"
    
    library(zoo)
    library(chron)
    toChron <- function(d, t) as.chron(paste(d, t))
    z <- read.zoo(text = Lines, index = 1:2, FUN = toChron)
    aggregate(z, trunc(time(z), "00:01:00"), mean)
    

    结果是:

    (05/05/11 09:30:00) (05/05/11 09:31:00) (05/05/11 09:32:00) 
                 97.224             100.280              98.280 
    

    【讨论】:

    • 简洁的代码......几乎就在那里,但我想每 30 秒而不是每分钟聚合一次。
    • 将一分钟的引用替换为 30 秒。
    【解决方案2】:

    我希望我们可以假设这是在 zoo 或 xts 对象中。如果是这样,那么试试这个:

      # First get a start for a set of intervals, need to use your tz
    beg<- as.POSIXct( format(index(dat[1,]), "%Y-%m-%d %H:%M", tz="EST5EDT"))
      # Then create a sequence of 30 second intervals
    tseq <- beg+seq(0,4*30, by=30)
      # Then this will creat a vector than you can use for your aggregation fun
    findInterval(index(dat), tseq)
      #[1] 1 1 1 2 2 3 4 5
      # To find the first row in a subset of rows from tapply, try "[" with 1
    tapply(dat, findInterval(index(dat), tseq), "[", 1)
      #     1      2      3      4      5 
      #101.32  89.66 100.28 100.28  98.28 
    

    【讨论】:

    • 我永远不会想到尝试这种方法。有趣...顺便说一句,您能解释一下为什么在创建序列时使用 4*30 吗?我不明白那部分。
    • 您需要一个大于上次观察的结束时间。如果你想计算(你可能应该),那么你需要使用 max(index(dat))+30 来确保 findInterval 的区间向量足够长。
    【解决方案3】:

    我会简单地将时间截断到您的时间间隔,因此假设t 是时间(如果不是,请使用as.POSIXct

    bucket = t - as.numeric(t) %% 30
    

    然后你可以聚合bucket,比如aggregate(value, list(bucket), sum)

    (我不使用zoo,所以这是纯R)

    【讨论】:

      【解决方案4】:

      您应该查看xts 中的align.time。它所做的事情非常接近您想要实现的目标。

      my.data <- read.table(text="date,x
      2011-05-05 09:30:04,101.32
      2011-05-05 09:30:14,100.09
      2011-05-05 09:30:19,99.89
      2011-05-05 09:30:35,89.66
      2011-05-05 09:30:45,95.16
      2011-05-05 09:31:12,100.28
      2011-05-05 09:31:50,100.28
      2011-05-05 09:32:10,98.28", header=TRUE, as.is=TRUE,sep = ",")
      
      my.data <- xts(my.data[,2],as.POSIXlt(my.data[,1],format="%Y-%m-%d %H:%M:%S"))
      
      library(xts)
      res <-align.time(my.data,30)
      res[!duplicated(index(res)),]
      
                            [,1]
      2011-05-05 09:30:30 101.32
      2011-05-05 09:31:00  89.66
      2011-05-05 09:31:30 100.28
      2011-05-05 09:32:00 100.28
      2011-05-05 09:32:30  98.28
      

      如果让解释更清晰,您可以将时间序列滞后 30 秒。

      【讨论】:

      • 我错过了什么吗?我看不到(自定义)聚合在哪里完成......结果看起来是正确的,但我看不到使用上面的 sn-p 是如何实现的
      • 你没有告诉我们你想如何聚合(意思是,VWAP...)。我做了和你一样的事情:每 30 秒只选择第一笔交易。这就是!duplicated 所做的。
      猜你喜欢
      • 2012-02-27
      • 1970-01-01
      • 2011-12-14
      • 1970-01-01
      • 1970-01-01
      • 2017-10-14
      • 2014-03-26
      • 2021-03-05
      • 2021-04-19
      相关资源
      最近更新 更多