假设我有以下动物园对象:
x.orig <- read.zoo(data.frame(date=seq(as.Date('2020-01-01'), as.Date('2020-01-10'), 1), v=c(1,2,3,100,4,5,1000,8,8,10)))
2020-01-01 2020-01-02 2020-01-03 2020-01-04 2020-01-05 2020-01-06 2020-01-07 2020-01-08 2020-01-09 2020-01-10
1 2 3 100 4 5 1000 8 8 10
我想如下计算width=seq_along(x.orig)
的滚动总和:
2020-01-01 1
2020-01-02 1 + 2 #2020-01-01 + 2020-01-02
2020-01-03 1 + (1 + 2) + 3 #2020-01-01 + 2020-01-02 + 2020-01-03
2010-01-04 1 + (1 + 2) + (1 + (1 + 2) + 3) + 100 #2020-01-01 + 2020-01-02 + 2020-01-03 + 2020-01-04
...
我想这样做的方法是以某种方式对x进行结果馈送,以便在每个rollapply循环后更新x,以便下一个rollapply迭代在其窗口中拾取修改后的值,但不确定如何写...
我不认为这很常见,因此可能不会有此功能,但是您可以使用Rcpp
修改自己的快速功能,这是一个示例:
library(data.table)
library(Rcpp)
DT <- data.table(date=seq(as.Date('2020-01-01'), as.Date('2020-01-10'), 1),
v=c(1,2,3,100,4,5,1000,8,8,10))
DT[, week := 1:.N %/% 7] # create a week column (you can adapt this to your needs)
# Add your logic to a cpp function
cppFunction("
IntegerVector roll_cumsum(IntegerVector x) {
int n = x.size();
int cumsum = x[0];
IntegerVector y = clone(x);
for (int i = 1; i < n; ++i) {
y[i] = x[i] + cumsum;
cumsum += y[i];
}
return y;
}
")
DT[, result := roll_cumsum(v), by = week][]
这是我的尝试。理想情况下,我想在每次迭代后都修改x.orig
,但无法正常工作,因此又创建了一个名为latest
的变量。我怀疑这是最好的方法:
library(zoo)
latest <- x.orig
rollapplyr(x.orig, width = seq_along(x.orig), function(x) {
#browser()
x <- latest[index(x)]
v <- sum(x)
if (!is.na(v))
latest[last(index(x))] <<- v
latest[last(index(x))]
})
2020-01-01 2020-01-02 2020-01-03 2020-01-04 2020-01-05 2020-01-06 2020-01-07 2020-01-08 2020-01-09 2020-01-10
1 3 7 111 126 253 1501 2010 4020 8042