R中的时间序列数据滑动时间间隔

15
我正在尝试提取不规则时间序列数据集的有趣统计信息,但是在寻找适合工作的正确工具方面遇到了困难。虽然很容易找到用于操作定期采样的时间序列或任何时间的基于索引的系列的工具,但我在解决问题方面没有什么运气。
首先,一个可重复的数据集:
library(zoo)
set.seed(0)
nSamples    <- 5000
vecDT       <- rexp(nSamples, 3)
vecTimes    <- cumsum(c(0,vecDT))
vecDrift    <- c(0, rnorm(nSamples, mean = 1/nSamples, sd = 0.01))
vecVals     <- cumsum(vecDrift)
vecZ        <- zoo(vecVals, order.by = vecTimes)
rm(vecDT, vecDrift)

假设时间单位为秒。在 vecZ 序列中,有将近 1700 秒(略少于30分钟)的时间,期间有5001个条目。(注:我会尝试使用 xts,但是它似乎需要日期信息,而当不相关时,我宁愿不使用特定日期。)
我的目标如下:
  • 找到每个点前后3分钟的值的索引。由于时间是连续的,我怀疑任何两个点都精确地相隔3分钟。我想要找到的是在给定点之前不超过3分钟,在至少3分钟之后的点,即类似以下伪代码的内容:

    backIX(t, vecZ, tDelta) = min{ix in length(vecZ) : t - time(ix) < tDelta} forwardIX(t, vecZ, tDelta) = min{ix in length(vecZ) : time(ix) - t > tDelta}

    因此,对于3分钟,tDelta = 180。如果t=2500,那么forwardIX() 的结果将是3012(即time(vecZ)[2500]为860.1462,time(vecZ)[3012]为1040.403,或超过180秒),而backwardIX() 的输出将为2020(对应时间为680.7162秒)。

    理想情况下,我希望使用不需要t的函数,因为这将需要对函数进行length(vecZ)次调用,忽略了可以更有效地计算时间滑动窗口的事实。

  • 对时间滚动窗口中的所有值应用一个函数。我看到过rollapply,它使用固定的窗口大小(即固定数量的索引,但不是固定的时间窗口)。我可以用一个循环(或foreach ;-))来计算每个索引t,但我想知道是否已经有一些简单的函数实现了,例如计算给定时间范围内所有值的平均值的函数。由于这可以通过滑动窗口的简单汇总统计信息有效地完成,因此应该比访问所有数据多次以计算每个统计量的函数更具计算效率。一些相当自然的函数:平均值、最小值、最大值和中位数。

    即使窗口的大小不随时间变化,也可以变化窗口的大小,并且可以使用上述问题的结果找到窗口的大小。但是,这仍然需要额外的计算,因此能够指定基于时间的区间似乎更有效率。

在R中是否有可以方便进行时间窗口数据操作的包,还是我需要自己编写函数?


注意1:这个问题旨在实现类似的功能,但是针对不相交的时间段,而不是滚动时间窗口,例如,我可以将此适应于每个连续的3分钟块上进行分析,但我不知道如何将其调整为滚动3分钟间隔。
注意2:我发现从zoo对象切换到数字向量(用于时间)显着加快了第一个目标的范围查找/窗口端点识别问题。那仍然是一个天真的算法,但值得一提的是,使用zoo对象可能不是天真方法的最佳选择。

@GSee 谢谢,不过在我看来,这些函数将数据分割成连续的不相交区间(正如我在问题后附注中提到的)。如果有一种方法可以制作滑动/滚动时间窗口,我还没有想出如何让 xts 这样做。 - Iterator
@GSee 你把我难住了。 :) 我还没看出那怎么能行,但是我会再多想一下的。我现在知道rollapply支持将width作为列表 - 我只需要弄清楚如何获得那个列表就可以了。 - Iterator
如果你想保留微秒级时间戳,我的方法会让你的对象变得非常非常大。我应该重新考虑一下。 - GSee
请查看 sqldf 主页上的 4h 和 4i 示例:http://sqldf.googlecode.com。 - G. Grothendieck
@G.Grothendieck 很有趣,谢谢。我很想尝试使用data.table,因为我对它相对熟悉,但是sqldf也非常吸引人。 - Iterator
显示剩余4条评论
2个回答

1

这是我建议的,但我不确定它是否完全回答了你的问题。

#Picking up where your code left off
library(xts)
library(TTR)
x <- .xts(vecZ, vecTimes)
xx <- na.locf(cbind(xts(, seq.POSIXt(from=start(x), to=end(x), by='sec')), x))
x$means <- runMean(xx, n=180)
out <- x[!is.na(x[, 1]), ]
tail(out)

                                  x     means
1969-12-31 18:28:17.376141 0.2053531 0.1325938
1969-12-31 18:28:17.379140 0.2101565 0.1329065
1969-12-31 18:28:17.619840 0.2139770 0.1332403
1969-12-31 18:28:17.762765 0.2072574 0.1335843
1969-12-31 18:28:17.866473 0.2065790 0.1339608
1969-12-31 18:28:17.924270 0.2114755 0.1344264

1
截至2016年11月25日在CRAN上发布的版本v1.9.8中, 已经具备了在非等值连接中进行聚合的能力,可以用于在不规则时间序列的滑动时间窗口上应用滚动函数。为了演示和验证,使用了一个较小的数据集。
library(data.table)   # development version 1.11.9 used

# create small dataset
set.seed(0)
nSamples    <- 10
vecDT       <- rexp(nSamples, 3)
vecTimes    <- cumsum(c(0,vecDT))
vecVals     <- 0:nSamples
vec         <- data.table(vecTimes, vecVals)
vec
      vecTimes vecVals
 1: 0.00000000       0
 2: 0.06134553       1
 3: 0.10991444       2
 4: 0.15651286       3
 5: 0.30186907       4
 6: 1.26685858       5
 7: 1.67671260       6
 8: 1.85660688       7
 9: 2.17546271       8
10: 2.22447804       9
11: 2.68805641      10
# define window size in seconds 
win_sec = 0.3

# aggregate in sliding window by a non-equi join
vec[.(t = vecTimes, upper = vecTimes + win_sec, lower = vecTimes - win_sec), 
    on = .(vecTimes < upper, vecTimes > lower), 
    .(t, .N, sliding_mean = mean(vecVals)), by = .EACHI]
     vecTimes     vecTimes          t N sliding_mean
 1: 0.3000000 -0.300000000 0.00000000 4          1.5
 2: 0.3613455 -0.238654473 0.06134553 5          2.0
 3: 0.4099144 -0.190085564 0.10991444 5          2.0
 4: 0.4565129 -0.143487143 0.15651286 5          2.0
 5: 0.6018691  0.001869065 0.30186907 4          2.5
 6: 1.5668586  0.966858578 1.26685858 1          5.0
 7: 1.9767126  1.376712596 1.67671260 2          6.5
 8: 2.1566069  1.556606875 1.85660688 2          6.5
 9: 2.4754627  1.875462707 2.17546271 2          8.5
10: 2.5244780  1.924478037 2.22447804 2          8.5
11: 2.9880564  2.388056413 2.68805641 1         10.0

前两列分别显示时间间隔的上限和下限,t 是原始的 vecTimesN 表示计算滑动平均所包含的数据点数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接