【发布时间】:2012-05-15 00:16:38
【问题描述】:
我正在尝试为不规则的时间序列数据集提取有趣的统计数据,但未能找到适合该工作的工具。很容易找到用于处理任何时间定期采样的时间序列或基于索引的序列的工具,尽管我在尝试解决的问题上运气不佳。
首先,一个可重现的数据集:
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,但xts 似乎需要日期信息,我宁愿在不相关时不使用特定日期。)
我的目标如下:
-
确定每个点之前 3 分钟和之后 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:This question 试图做类似的事情,除了不相交的间隔,而不是滚动的时间窗口,例如我可以调整它以对每个连续的 3 分钟块进行分析,但我没有看到一种方法可以调整它以滚动 3 分钟间隔。
注意 2:我发现从 zoo 对象切换到数字向量(对于时代而言)显着加快了第一个目标的范围查找/窗口端点识别问题。这仍然是一种幼稚的算法,但值得一提的是,使用 zoo 对象可能不是幼稚方法的最佳选择。
【问题讨论】:
-
我认为
xts可能是要走的路。请参阅?endpoints、?to.period、?period.apply和?split.xts。像这样将您的对象强制为 xts:x <- .xts(vecVals, vecTimes) -
@GSee 谢谢,尽管在我看来,这些函数将数据拆分为连续的、不相交的间隔(如我附加到问题的注释中所述)。如果有办法制作滑动/滚动时间窗口,我还没有弄清楚如何让
xts做到这一点。 -
您可以合并一个零宽度的严格规则 xts 对象和
na.locf以使您的数据严格规则。然后使用rollapply -
@GSee 你难倒我了。 :) 我还没有看到它是如何工作的,但我会考虑更多。我现在看到
rollapply支持width作为列表 - 我想我只需要弄清楚如何获取该列表。 -
嗯。如果你想保持微秒时间戳,我的方法会让你的对象变得更大,更大。我应该重新考虑..
标签: r time-series data-manipulation