【问题标题】:Pass the `width` parameter of `zoo:rollapply` as argument to the called function将 `zoo:rollapply` 的 `width` 参数作为参数传递给被调用函数
【发布时间】:2020-02-06 11:42:46
【问题描述】:

如何将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 的每个滚动窗口a$w 的对应值。例如:

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

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

因此期望的输出是:

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

【问题讨论】:

    标签: r zoo rollapply


    【解决方案1】:

    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 时递增并返回它。

    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
    

    【讨论】:

    • 谢谢 - 我的例子被错误地选择为太简单了。我真的需要函数内部的width 参数,因为它里面的东西的值取决于它(我稍后会编辑我的问题)
    • 已添加(2)和(3)。
    • 谢谢!有趣的建议 - 2a 给我带来了新的东西,谢谢!重新考虑一下...实际上,可以在函数内部使用length(x) 并适当管理边框/partial 方面...?
    • 如果您使用居中对齐,一般不会。考虑rollapply(1:5, 3, toString, partial = TRUE) 在第一次迭代中返回“1, 2”,在最后一次迭代中返回“4, 5”,但如果您的输入是 1:2 或 4:5,您不知道第一个是number 是索引或第二个是。实际上它是“1, 2”的第一个数字,但它是“4, 5”的第二个数字。
    猜你喜欢
    • 2013-01-27
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    相关资源
    最近更新 更多