Reputation: 445
I have two vectors. Every day I want to add a row to make the dataset one row larger:
day1 <- c(0,0,8,10,4,5,3,5,6,10,7,11,9,7,10,13,8,7,5,4)
day2 <- c(0,0,8,10,4,5,3,5,6,10,7,11,9,7,10,13,8,7,5,4,0)
I have two functions that act as a cumulative mean and a rolling mean respectively. Both give the average with a lag of 1.
cumroll <- function(x) {
if(length(x)<=1) {x}
else {
x <- head(x, -1)
c(head(x,1), cumsum(x) / seq_along(x))
}
}
rollmean <- function(x, n) {if (length(x) <= n) cumroll(x) else rollapply(x,list(-seq(n)), mean, fill = cumroll(x))}
I am looking to do a rolling average of 20 on both datasets using this code:
day1_avg <- ave(day1, FUN = function(x) rollmean(x, 20))
day2_avg <- ave(day2, FUN = function(x) rollmean(x, 20))
When I run the day1_avg it acts as I would expect, with the cumroll acting since there has only been 20 observations. However when I run day2_avg with 21 observations, every value before the 21st observation is automatically given 0 rather than the cumroll values.
Results are below with my desired output for day2_avg:
day2 day1_avg day2_avg DESIRED
0 0 0 0
0 0 0 0
8 0 0 0
10 2.666667 0 2.666667
4 4.5 0 4.5
5 4.4 0 4.4
3 4.5 0 4.5
5 4.285714 0 4.285714
6 4.375 0 4.375
10 4.555556 0 4.555556
7 5.1 0 5.1
11 5.272727 0 5.272727
9 5.75 0 5.75
7 6 0 6
10 6.071429 0 6.071429
13 6.333333 0 6.333333
8 6.75 0 6.75
7 6.823529 0 6.823529
5 6.833333 0 6.833333
4 6.736842 0 6.736842
0 6.6 6.6
I need to amend the functions somehow to make sure that cumroll values remain the same after the nth observation of the rollmean kicks in.
Any help would be hugely appreciated!
Upvotes: 0
Views: 103
Reputation: 5152
Change your rollmean
:
rollmean <- function(x, n) {if (length(x) <= n) tmp<- cumroll(x)
else {tmp<-rollapply(x,list(-seq(n)), mean, fill = cumroll(x))
tmp[1:n]<-cumroll(x[1:n])
}
tmp}
You will get:
> tail(cbind(day1,day1_avg,day2,day2_avg))
day1 day1_avg day2 day2_avg
[17,] 8 6.750000 8 6.750000
[18,] 7 6.823529 7 6.823529
[19,] 5 6.833333 5 6.833333
[20,] 4 6.736842 4 6.736842
[21,] 0 0.000000 0 6.600000
[22,] 0 0.000000 1 6.600000
Upvotes: 2