什么是从数据帧中的带时间戳的行分区和聚合间隔的有效方法?

时间:2010-03-14 04:04:25

标签: r xts

从带有时间戳行的数据框(strptime结果)中,聚合间隔统计信息的最佳方法是什么?

间隔可能是一小时,一天等。

aggregate函数,但这对于将每一行分配给一个区间没有帮助。我打算在数据框中添加一个表示间隔的列,并将其与aggregate一起使用,但是如果有更好的解决方案,那么听听它会很棒。

感谢您的任何指示!


示例数据

五行,时间戳从03:00开始分为15分钟。

时间间隔1

  • “2010-01-13 03:02:38 UTC”
  • “2010-01-13 03:08:14 UTC”
  • “2010-01-13 03:14:52 UTC”

时间间隔2

  • “2010-01-13 03:20:42 UTC”
  • “2010-01-13 03:22:19 UTC”

结论

使用xts等时间序列包应该是解决方案;但是我没有成功使用它们并使用cut进行了啰嗦。因为我目前只需绘制直方图,行按间隔分组,这就足够了。

cut喜欢这样使用:

interv <- function(x, start, period, num.intervals) {
  return(cut(x, as.POSIXlt(start)+0:num.intervals*period))
}

3 个答案:

答案 0 :(得分:6)

使用time series package. xts包具有专门为此设计的功能。或者查看zoo包中的聚合和rollapply函数。

rmetrics电子书有一个有用的讨论,包括各种包的性能比较:https://www.rmetrics.org/files/freepdf/TimeSeriesFAQ.pdf

编辑:查看my answer to this question。基本上,您需要将每个时间戳截断为特定的时间间隔,然后使用这些新的截断时间戳作为分组向量进行聚合。

答案 1 :(得分:6)

分割向量的标准函数是cutfindInterval

v <- as.POSIXct(c(
  "2010-01-13 03:02:38 UTC",
  "2010-01-13 03:08:14 UTC",
  "2010-01-13 03:14:52 UTC",
  "2010-01-13 03:20:42 UTC",
  "2010-01-13 03:22:19 UTC"
))

# Your function return list:
interv(v, as.POSIXlt("2010-01-13 03:00:00 UTC"), 900)
# [[1]]
# [1] "2010-01-13 03:00:00"
# [[2]]
# [1] "2010-01-13 03:00:00"
# [[3]]
# [1] "2010-01-13 03:00:00"
# [[4]]
# [1] "2010-01-13 03:15:00 CET"
# [[5]]
# [1] "2010-01-13 03:15:00 CET"

# cut returns factor, you must provide proper breaks:
cut(v, as.POSIXlt("2010-01-13 03:00:00 UTC")+0:2*900)
# [1] 2010-01-13 03:00:00 2010-01-13 03:00:00 2010-01-13 03:00:00
# [4] 2010-01-13 03:15:00 2010-01-13 03:15:00
# Levels: 2010-01-13 03:00:00 2010-01-13 03:15:00

# findInterval returns vector of interval id (breaks like in cut)
findInterval(v, as.POSIXlt("2010-01-13 03:00:00 UTC")+0:2*900)
# [1] 1 1 1 2 2

对于记录:cutPOSIXt类型的方法,但遗憾的是无法提供start参数,效果是:

cut(v,"15 min")
# [1] 2010-01-13 03:02:00 2010-01-13 03:02:00 2010-01-13 03:02:00
# [4] 2010-01-13 03:17:00 2010-01-13 03:17:00
# Levels: 2010-01-13 03:02:00 2010-01-13 03:17:00

如你所见,它的开始于03:02:00。您可能会混淆输出因子的标签(将标签转换为时间,以某种方式转换并转换回字符)。

答案 2 :(得分:0)

这是一个有趣的问题;随着各种时间序列包和方法的激增,应该采用一种方法来对不规则的时间序列进行分类,而不是通过OP提出的蛮力。这是一种“高级”方式,可以使用aggregate等人使用cut对象定义的chron版本来获取时间间隔。

require(chron)
require(timeSeries)

my.times <- "
2010-01-13 03:02:38 UTC
2010-01-13 03:08:14 UTC
2010-01-13 03:14:52 UTC
2010-01-13 03:20:42 UTC
2010-01-13 03:22:19 UTC
"

time.df <- read.delim(textConnection(my.times),header=FALSE,sep="\n",strip.white=FALSE)
time.seq <- seq(trunc(timeDate(time.df[1,1]),units="hours"),by=15*60,length=nrow(time.df))
intervals <- as.numeric(cut(as.chron(as.character(time.df$V1)),breaks=as.chron(as.character(time.seq))))

你得到了

intervals  
[1] 1 1 1 2 2

您现在可以将其附加到数据框并进行聚合。

上面的coersion杂技(从character到timeDate到character到chron)有点不幸,所以如果有更清晰的解决方案来使用xts或任何其他timeSeries包装来分类不规则的时间数据,我很想知道他们也是!..

我也很想知道什么是最有效的分组大型高频不规则时间序列的方法,例如:为流动性股票创建1到4分钟的交易量数据栏。