将 `zoo:rollapply` 的 `width` 参数作为参数传递给被调用函数

Pass the `width` parameter of `zoo:rollapply` as argument to the called function

如何将 zoo:rollapply 函数的 width 参数传递给 rollapply 中调用的 FUN 函数?

我将值和宽度作为相同的列 data.frame:

library(zoo)
a = data.frame(v = 1:10, w = c(2,1,3,5,2,7,3,2,1,3))
#     v w
# 1   1 2
# 2   2 1
# 3   3 3
# 4   4 5
# 5   5 2
# 6   6 7
# 7   7 3
# 8   8 2
# 9   9 1
# 10 10 3

我能做到:

rollapply(a$v, a$w, function(x) sum(x), partial=T)

给出:

[1] 3 2 9 20 11 42 21 17 9 19

现在我想在计算中使用a$v的每个滚动window,相应的a$w值。例如:

rollapply(a$v, a$w, function(x) sum(x) + a$w[1], partial=T)

但我不想将 a$w[1] 作为常量值(在这里,它只是将上面的值加 2),我想使用 a$w 中的值,每次都对应于 a$w(即在 a 的同一行)。

因此,所需的输出将是:

[1] 5 3 12 25 13 49 24 19 10 22

1) 宽度不需要在函数中。以后可以补充:

rollapply(a$v, a$w, sum, partial = TRUE) + a$w
## [1]  5  3 12 25 13 49 24 19 10 22

如果您想要不同的对齐方式,请指定 align=

2)这种方式有点丑,不过还有一种方式就是维护一个外部索引。

i <- 0
rollapply(a$v, a$w, function(x) sum(x) + a$w[i <<- i+1], partial = TRUE)
## [1]  5  3 12 25 13 49 24 19 10 22

2a) 这可以通过使用面向对象的思想来维护状态的额外代码来稍微清理一下。这里我们定义了一个原型对象p,它有一个内部计数器和一个incr方法,每次在对象上调用incr时,它都会递增和returns它。

library(proto)
p <- proto(counter = 0, incr = function(.) .$counter <- .$counter + 1)
rollapply(a$v, a$w, function(x) sum(x) + a$w[p$incr()], partial = TRUE)
## [1]  5  3 12 25 13 49 24 19 10 22

3) 问题中的示例使用了居中对齐,但如果您确实需要右对齐或左对齐,则可以通过遍历 a 而不仅仅是超过 a$v。这里是为了右对齐。

Sum <- function(x) {
  x <- matrix(x,,2)
  v <- x[, 1]
  w <- tail(x[, 2], 1)
  sum(v) + w
}
rollapplyr(a, a$w, Sum, partial = TRUE, by.column = FALSE)
## [1]  3  3  9 15 11 28 21 17 10 30

# double check
rollapplyr(a$v, a$w, sum, partial = TRUE) + a$w
## [1]  3  3  9 15 11 28 21 17 10 30