6

例如,假设您xts从上午 9:30 到下午 4:30 有大约 10 年每天 1 分钟的工具 x 数量数据,如下(格式):

    Date.Time               Volume        
    2001-01-01 09:30:00     1200
    2001-01-01 09:31:00     1110
    2001-01-01 09:32:00     1303

一直到:

    2010-12-20 16:28:00     3200
    2010-12-20 16:29:00     4210
    2010-12-20 16:30:00     8303

我想:

  • 获取整个系列每分钟的平均音量(即所有 10 年 9:30、9:31、9:32...16:28、16:29、16:30 时的平均音量)

我应该怎么做最好:

  • 将数据聚合到一分钟的存储桶中
  • 获取这些桶的平均值
  • 将那些“平均”桶重构回单个 xts/zoo 时间序列?

我对aggregate, sapply,period.apply函数等进行了很好的探索,但似乎无法正确“分类”数据。

用循环解决这个问题很容易,但速度很慢。我宁愿避免使用编程解决方案并使用利用 C++ 架构的功能(即xts基于解决方案)

谁能提供一些建议/解决方案?

提前非常感谢。

4

2 回答 2

5

首先让我们创建一些测试数据:

library(xts) # also pulls in zoo
library(timeDate)
library(chron) # includes times class

# test data
x <- xts(1:3, timeDate(c("2001-01-01 09:30:00", "2001-01-01 09:31:00", 
    "2001-01-02 09:30:00")))

1)聚合.动物园。现在尝试将其转换为times类并使用此单行进行聚合:

aggregate(as.zoo(x), times(format(time(x), "%H:%M:%S")), mean)

1a)aggregate.zoo(变体)。或者这种将较短的聚合系列转换times为避免在较长的原始系列上进行的变体:

ag <- aggregate(as.zoo(x), format(time(x), "%H:%M:%S"), mean)
zoo(coredata(ag), times(time(ag)))

2) 轻按。另一种方法tapply可能更快:

ta <- tapply(coredata(x), format(time(x), "%H:%M:%S"), mean)
zoo(unname(ta), times(names(ta)))

编辑:简化(1)并添加(1a)和(2)

于 2012-02-24T13:25:15.260 回答
3

这是一个解决方案ddply,但您也可以使用sqldf, tapply, aggregate,by等。

# Sample data
minutes <- 10 * 60
days <- 250 * 10
d <- seq.POSIXt( 
  ISOdatetime( 2011,01,01,09,00,00, "UTC" ), 
  by="1 min", length=minutes 
)
d <- outer( d, (1:days) * 24*3600, `+` )
d <- sort(d)
library(xts)
d <- xts( round(100*rlnorm(length(d))), d )

# Aggregate
library(plyr)
d <- data.frame( 
  minute=format(index(d), "%H:%M"), 
  value=coredata(d) 
)
d <- ddply( 
  d, "minute", 
  summarize, 
  value=mean(value, na.rm=TRUE) 
)

# Convert to zoo or xts
zoo(x=d$value, order.by=d$minute) # The index does not have to be a date or time
xts(x=d$value, order.by=as.POSIXct(sprintf("2012-01-01 %s:00",d$minute), "%Y-%m-%d %H:%M:%S") )
于 2012-02-24T07:18:07.917 回答