假设我有一个动物园对象(或者它可能是一个data.frame),它具有“一天中的时间”的索引并具有一定的值(请参阅下面的示例数据):
val
...
2006-08-01 12:00 23
2006-08-01 12:01 24
2006-08-01 12:02 25
2006-08-01 12:03 26
2006-08-01 12:04 27
2006-08-01 12:05 28
2006-08-01 12:06 29
...
2006-08-02 12:00 123
2006-08-02 12:01 124
2006-08-02 12:02 125
2006-08-02 12:03 126
2006-08-02 12:04 127
...
我想在每次出现该间隔时从12:01-12:03(即类似于zoo :: rollapply)调用自定义函数(称为custom.func(vals)
),因此在此示例中,每天都这样。我该怎么办?
注意(出于鲁棒性,考虑以下边缘情况也很重要,但不是必须的::
custom.func(vals)
一样在日期范围内调用val
怎么办?我推荐runner程序包,该程序包可以计算不规则时间序列上的任何滚动函数。函数runner与rollApply
等效,区别在于它可以取决于日期。 runner
允许在日期为k
(或任何整数)的idx
定义的窗口长度上应用任何R函数。以下示例在5分钟(5 * 60秒)的窗口跨度上计算回归。算法不在乎是否会更改日期,每次只计算5分钟(例如23:56-00:01)。
创建数据:
set.seed(1)
x <- cumsum(rnorm(1000))
y <- 3 * x + rnorm(1000)
time <- as.POSIXct(cumsum(sample(60:120, 1000, replace = TRUE)),
origin = Sys.Date()) # unequaly spaced time series
data <- data.frame(time, y, x)
要在滑动窗口上调用的自定义函数:
library(runner)
running_regression <- function(idx) {
predict(lm(y ~ x, data = data))[max(idx)]
}
data$pred <- runner(seq_along(x),
k = 60 * 5,
idx = time,
f = running_regression)
一旦我们创建了具有5分钟滚动预测的数据集,那么我们就只能过滤特定的窗口-在这里,仅每小时的1分钟。这意味着我们始终保持{hh}:56-{hh + 1}:01
library(dplyr)
library(lubridate)
filtered <-
data %>%
filter(minute(time) == 1)
plot(data$time, data$y, type = "l", col = "red")
points(filtered$time, filtered$pred, col = "blue")
vignette中还有一些其他示例如何使用runner
来做到这一点
假设我们的输入是末尾注释中给出的POSIXct动物园对象z
。
创建一个字符向量times
,每个z
元素具有一个元素,格式为HH:MM。然后创建一个逻辑ok
,该逻辑z[ok]
指示哪些时间在指示的边界值之间。然后将z
减小到那些值。最后,每天使用sum
来应用aggregate.zoo
(如果需要,可以使用其他功能):
times <- sub("....-..-.. (..:..):..", "\\1", time(z)) # HH:MM
ok <- times >= "12:01" & times <= "12:03"
aggregate(z[ok], as.Date, sum)
## 2006-08-01 2006-08-02
## 75 375
Lines <- "datetime val
2006-08-01T12:00 23
2006-08-01T12:01 24
2006-08-01T12:02 25
2006-08-01T12:03 26
2006-08-01T12:04 27
2006-08-01T12:05 28
2006-08-01T12:06 29
2006-08-02T12:00 123
2006-08-02T12:01 124
2006-08-02T12:02 125
2006-08-02T12:03 126
2006-08-02T12:04 127"
library(zoo)
z <- read.zoo(text = Lines, tz = "", header = TRUE, format = "%Y-%m-%dT%H:%M")