题
从带有时间戳行的数据帧(strptime 结果)中,聚合间隔统计信息的最佳方法是什么?
间隔可以是一小时、一天等。
有的是 aggregate
函数,但这无助于将每一行分配给一个间隔。我计划在数据框中添加一列来表示间隔并将其与 aggregate
, ,但如果有更好的解决方案,那就很高兴听到它。
感谢您的指点!
示例数据
包含时间戳的五行从 03:00 开始分为 15 分钟间隔。
间隔1
- “2010-01-13 03:02:38 世界标准时间”
- “2010-01-13 03:08:14 世界标准时间”
- “2010-01-13 03:14:52 世界标准时间”
间隔2
- “2010-01-13 03:20:42 世界标准时间”
- “2010-01-13 03:22:19 世界标准时间”
结论
使用时间序列包,例如 xts
应该是解决方案;但是我没有成功使用它们并最终使用 cut
. 。由于我目前只需要绘制直方图,并按间隔对行进行分组,这就足够了。
cut
使用方式如下:
interv <- function(x, start, period, num.intervals) {
return(cut(x, as.POSIXlt(start)+0:num.intervals*period))
}
解决方案
分割向量的标准函数是 cut
和 findInterval
:
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
作为记录: cut
有一个方法 POSIXt
类型,但不幸的是没有办法提供 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 开始。您可能会弄乱输出因子的标签(将标签转换为时间,以某种方式舍入并转换回字符)。
其他提示
用一个 时间序列包。 xts 包具有专门为此目的而设计的函数。或者看看zoo包中的aggregate和rollapply函数。
rmetrics 电子书有一个有用的讨论,包括各种包的性能比较: https://www.rmetrics.org/files/freepdf/TimeSeriesFAQ.pdf
编辑:看着 我对这个问题的回答. 。基本上,您需要将每个时间戳截断为特定的时间间隔,然后使用这些新的截断时间戳作为分组向量进行聚合。
这是个有趣的问题;随着各种时间序列包和方法的激增,应该有一种对不规则时间序列进行分箱的方法,而不是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
您现在可以将其附加到数据框并聚合。
上面的强制转换(从字符到 timeDate 到字符到 chron)有点不幸,所以如果有更干净的解决方案使用 xts 或任何其他 timeSeries 包对不规则时间数据进行分箱,我也很想听听它们!..
我也很想知道对大型高频不规则时间序列进行分箱的最有效方法是什么,例如为流动性非常强的股票创建 1 分钟成交量柱。