在FUN中使用rollapply width参数具有意外结果

时间:2019-01-17 18:07:18

标签: r xts rollapply

我正在使用rollapply进行计算,该计算将卷中的最后一个值除以平均值减去一个,这样可以很好地工作,您可以自己尝试一下:

set.seed(123)
v <- xts(rnorm(5, 5, 1), Sys.Date()-5:1)
rollapplyr(v, width = 3, function(x) x[3, ] / mean(x) - 1)

                  [,1]
2019-01-12          NA
2019-01-13          NA
2019-01-14  0.24784729
2019-01-15 -0.07241364
2019-01-16 -0.08178780

然后,我还需要使用另一个参数来运行该函数,例如。 width = 4。当然,功能也需要调整:

rollapplyr(v, width = 4, function(x) x[4, ] / mean(x) - 1)

                  [,1]
2019-01-12          NA
2019-01-13          NA
2019-01-14          NA
2019-01-15 -0.02670674
2019-01-16 -0.04696956

为了更加灵活,我尝试将width参数直接传递到函数中,但得到了我没想到的结果,尽管第四列是正确的:

rollapplyr(v, width = 4, function(x, width) x[width, ] / mean(x) - 1)

                 [,1]        [,2]        [,3]        [,4]
2019-01-12         NA          NA          NA          NA
2019-01-13         NA          NA          NA          NA
2019-01-14         NA          NA          NA          NA
2019-01-15 -0.1478253 -0.08442393  0.25895593 -0.02670674
2019-01-16 -0.1137588  0.21861923 -0.05789086 -0.04696956

谁能理解在FUN中使用width参数在概念上有什么问题,以及如何解释输出?任何人都有一个正确的做法的想法吗?

1 个答案:

答案 0 :(得分:1)

您得到的结果等于这一行的结果:

rollapplyr(v, width = 4, function(x) x / mean(x) - 1)

只有一列时内部发生的事情是,您最终得到下面的代码行和一些已设置的变量。设置变量的结果已在代码中完成。 rollapply函数稍微复杂一些。

width <- 4
ind <- as.matrix(seq.int(4, 5))
# FUN passed on from rollappy
FUN <- match.fun(function(x, width) x[width, ] / mean(x) - 1)
sapply(ind, function(i) FUN(.subset_xts(v, 
                                        (i - width + 1):i)))

这些代码行之后是返回的xts的构建。

但是一旦您开始调试sapply部分中发生的事情(调试FUN),您就会发现width没有从sapply调用function(i ),因此在执行FUN时不可用。只有在rollapply内部定义了宽度的地方,.subset函数的宽度才可用。如果运行上面的代码行,也会发生相同的情况。这是由于在其中定义了width变量的环境以及在其中执行FUN的环境导致的。这些是不同的,这导致您得到结果。

最好的方法是将rollapply包装在另一个函数中,就像您在注释中提到的那样:

function(v,w) {
  rollapplyr(v, 
             width = w, 
             function(x) x[w, ] / mean(x) - 1)
}

此处w是在较高的环境级别上定义的,并且在创建rollapply中的FUN并随后在sapply中执行时可以正确传递w

有关环境的详细信息,您可以在高级R书籍中找到here