如何在5个月的时间内使用rollapply?

问题描述 投票:0回答:2

我在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解决方案,但其他库会很有趣

r zoo
2个回答
1
投票

由于宽度可以是宽度的向量,输入的每一行宽度,我们可以简单地计算每个日期和之前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的各种计算可能会根据略有不同的假设略有不同。


0
投票

改进G.格洛腾迪克的想法,我选择了:

  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)

看起来它工作正常......

© www.soinside.com 2019 - 2024. All rights reserved.