Reputation: 12077
So I have used zoo::rollapply()
fairly religiously but I don't think it is appropriate for the problem I am looking at. I have a requirement where I would like to implement a shrinking rolling window. So for example, here's some sample data:
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
I would like the rolling window to go in date descending order so rev(v$date)
for the order and I would like to sum the vals as follows [lagging by 1 every window] (each row below is a window):
5 + 4 + 3 + 2 + 1 = 15
4 + 3 + 2 + 1 = 10
3 + 2 + 1 = 6
2 + 1 = 3
1 = 1
so I expect my data.frame would be:
# 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
NOTE: Let's say the above example uses the
sum(x)
function to compute each window. It would be great to generalize this to anyfunction(x)
. Let's sayfunction(x) { (min(x) + max(x)) * length(x) * sum(x) }
NOTE: I would prefer a base R implementation but other packages that might be applicable would be interesting also
Upvotes: 0
Views: 92
Reputation: 269586
Use cumsum
and rev
like this:
transform(v, sum = rev(cumsum(vals)))
giving:
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
or noting that the width
argument can be a vector (see ?rollapply
):
library(zoo)
transform(v, sum = rev(rollapplyr(vals, seq_along(vals), sum)))
Upvotes: 1
Reputation: 2022
Here is one using 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
Upvotes: 1
Reputation: 26343
Try
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
Upvotes: 3