如何在5个月的窗口内使用rollapply?

时间:2019-04-04 21:11:37

标签: r zoo

rollapply()的文档中,我注意到这可以滚动3天:

## rolling mean by time window (e.g., 3 days) rather than
## by number of observations (e.g., when these are unequally spaced):
#
## - test data
tt <- as.Date("2000-01-01") + c(1, 2, 5, 6, 7, 8, 10)
z <- zoo(seq_along(tt), tt)
## - fill it out to a daily series, zm, using NAs
## using a zero width zoo series g on a grid
g <- zoo(, seq(start(z), end(z), "day"))
zm <- merge(z, g)
## - 3-day rolling mean
rollapply(zm, 3, mean, na.rm = TRUE, fill = NA)

假设我有以下数据:

data.zoo <- read.zoo(
                data.frame(
                    date = sample(seq(as.Date('2001-04-12'), as.Date("2019-04-05"), by="day"), 600), 
                    val = runif(1:600), 
                    val2 = runif(1:600)
               ))

是否可以将rollapply()与5个月的滚动窗口一起使用来计算val的滚动平均值? 5个月滚动窗口的问题在于一个月中的天数会有所不同...

注意:我希望使用base-R解决方案,但其他库也会很有趣

2 个答案:

答案 0 :(得分:1)

由于width可以是宽度的向量,因此输入的每一行一个,因此我们可以简单地计算出每个日期与5个月前的天数,并将这些数字用作宽度向量:

library(zoo)

ym <- as.yearmon(time(data.zoo))
w <- as.Date(ym) - as.Date(ym - 5/12)
r <- rollapplyr(data.zoo, w, mean, fill = NA)

或者,我们可以用lubridate这样写w

library(lubridate)
w <- time(data.zoo) - (time(data.zoo) %m-% months(5))

更新

如果可能缺少日期,则

library(lubridate)
w <- sapply(time(data.zoo), function(x)
  length(intersect(seq(x %m-% months(5), x, "day"), time(data.zoo)))

或重复此操作,将%m-% months(5)替换为subtract5m,而不会使用其他软件包:

subtract5m <- function(x) {
  if (length(x) == 1) seq(x, length = 2, by = "-5 month")[2]
  else as.Date(sapply(x, subtract5m))
}
w <- sapply(time(data.zoo), function(x)
  length(intersect(seq(subtract5m(x), x, "day"), time(data.zoo))))

请注意,由于5个月前的定义含糊不清,因此w的各种计算可能会基于略有不同的假设而略有不同。

答案 1 :(得分:0)

改进我所遵循的G. Grothendieck的想法:

  ym <- as.yearmon(time(data.zoo))
  ym.cutoff.ideal <- ym - 5/12
  ym.cutoff.closest.to.ideal <- as.yearmon(time(data.zoo)[findInterval(as.Date(ym.cutoff.ideal), as.Date(ym)) + 1])
  w <- time(data.zoo) - as.Date(ym.cutoff.closest.to.ideal) + 1
  r <- rollapplyr(data.zoo, w, mean, fill = NA)

看起来工作正常...