因此,我相当虔诚地使用了zoo::rollapply()
,但我认为它不适合我要解决的问题。我有一个要实现缩小的滚动窗口的要求。例如,这是一些示例数据:
v <- data.frame(date=as.Date("2012-1-2") + 0:4, vals=c(1,2,3,4,5))
v
date vals
1 2012-01-02 1
2 2012-01-03 2
3 2012-01-04 3
4 2012-01-05 4
5 2012-01-06 5
我希望滚动窗口按日期降序排列,所以用rev(v$date)
排序,我想对val求和,如下所示[每个窗口落后1](下面的每一行都是一个窗口):
5 + 4 + 3 + 2 + 1 = 15
4 + 3 + 2 + 1 = 10
3 + 2 + 1 = 6
2 + 1 = 3
1 = 1
所以我希望我的data.frame是:
# date vals new_val
#1 2012-01-02 1 1
#2 2012-01-03 2 3
#3 2012-01-04 3 6
#4 2012-01-05 4 10
#5 2012-01-06 5 15
注意:假设上面的示例使用
sum(x)
函数 计算每个窗口。将其推广到任何function(x)
。假设function(x) { (min(x) + max(x)) * length(x) * sum(x) }
注意:我更喜欢基本的R实现,但其他更喜欢的包 可能适用也很有趣
答案 0 :(得分:3)
尝试
v$new_val <- cumsum(v$vals)
v
# date vals new_val
#1 2012-01-02 1 1
#2 2012-01-03 2 3
#3 2012-01-04 3 6
#4 2012-01-05 4 10
#5 2012-01-06 5 15
答案 1 :(得分:1)
这里是一个使用sapply
v <- data.frame(date=as.Date("2012-1-2") + 0:4, vals=c(1,2,3,4,5))
v <- data.frame(v[order(rev(v$date)), ],
"new_val" = sapply(1:nrow(v), function(x) sum(v[order(rev(v$date)), "vals"][x:5])))
> v
date vals new_val
5 2012-01-06 5 15
4 2012-01-05 4 10
3 2012-01-04 3 6
2 2012-01-03 2 3
1 2012-01-02 1 1
答案 2 :(得分:1)
像这样使用cumsum
和rev
:
transform(v, sum = rev(cumsum(vals)))
给予:
date vals sum
1 2012-01-02 1 15
2 2012-01-03 2 10
3 2012-01-04 3 6
4 2012-01-05 4 3
5 2012-01-06 5 1
或注意到width
参数可以是向量(请参见?rollapply
):
library(zoo)
transform(v, sum = rev(rollapplyr(vals, seq_along(vals), sum)))