I\'m using the rollmean
function of zoo
package to calculate a simple 7-day moving average. The function has an argument align
and if I pu
align
has the same meaning in rollmean
and rollapply
but it is easier to see in rollapply
since using input data 1:8 and a window width of 3 and using toString
rather than mean
as the function to apply we can show which indexes are used at each point.
The alignment refers to which edge (or center) of the window is aligned with the current point as we iterate through successive positions of the input.
Thus using a window of length 3 it uses the value at the current position and the prior 2 positions for align = "right". For example, for the first position of the input 1:8 there is not a window of 3 values whose right end is at the first position so we get an NA. For the second position of the input there are only 2 positions to that point so again there is not a window of 3 positions whose right end is at the current position and so once again we get NA. For the third position there are three positions ending in position 3 so we pass c(1, 2, 3) to toString which formats them as seen below. For the 4th position there are again 3 positions whose right end is at position 4 so we get 2, 3, 4 and so on as shown on the first line marked ## in the code below.
For align = "center"
it places the center of the window at the current position so it uses the prior value, current value and next value.
For align = "left"
it places the left end of the window at the current position so it uses the current value and the next 2 values.
library(zoo)
x <- 1:8
rollapply(x, 3, toString, align = "right", fill = NA)
## [1] NA NA "1, 2, 3" "2, 3, 4" "3, 4, 5" "4, 5, 6" "5, 6, 7" "6, 7, 8"
rollapply(x, 3, toString, align = "center", fill = NA)
## [1] NA "1, 2, 3" "2, 3, 4" "3, 4, 5" "4, 5, 6" "5, 6, 7" "6, 7, 8" NA
rollapply(x, 3, toString, align = "left", fill = NA)
## [1] "1, 2, 3" "2, 3, 4" "3, 4, 5" "4, 5, 6" "5, 6, 7" "6, 7, 8" NA NA
Note that align = "center"
is the default if align=
is not specified and there are wrappers, rollmeanr
and rollapplyr
(note r
on the end), which default to align = "right"
.
I think it is instructive to see the results of all 3 next to each other:
library(zoo)
means <- sapply(c("right","center","left"),
function(x)zoo::rollmean(test,7,align = x, na.pad = TRUE))
cbind(test,means)
test right center left
[1,] 6 NA NA 19.28571
[2,] 50 NA NA 21.42857
[3,] 11 NA NA 15.28571
[4,] 16 NA 19.28571 15.00000
[5,] 1 NA 21.42857 19.42857
[6,] 26 NA 15.28571 25.28571
[7,] 25 19.28571 15.00000 22.71429
[8,] 21 21.42857 19.42857 24.42857
[9,] 7 15.28571 25.28571 22.00000
[10,] 9 15.00000 22.71429 23.42857
...
[40,] 41 27.28571 31.85714 33.57143
[41,] 49 29.42857 31.71429 33.85714
[42,] 35 33.71429 31.42857 30.00000
[43,] 20 31.85714 33.57143 26.85714
[44,] 44 31.71429 33.85714 25.42857
[45,] 28 31.42857 30.00000 NA
[46,] 18 33.57143 26.85714 NA
[47,] 43 33.85714 25.42857 NA
[48,] 22 30.00000 NA NA
[49,] 13 26.85714 NA NA
[50,] 10 25.42857 NA NA
?rollmean
says:
character specifying whether the index of the result should be left- or right-aligned or centered (default) compared to the rolling window of observations.
Let's look at a few different examples. I'll use rollmax
, since it's results are a little easier/faster to see than (say) rollmean
. Also, since I think padding helps the visualization, I'll include fill=NA
, ensuring that all returns are the same length as the input. Lastly, I'll rbind
them for vertical alignment.
set.seed(4)
vec <- sample(100, size = 15)
In the first window of width 5, it looks at the values between 59 and 79. The max is 79, and with align="left"
, it places the result in the far left of the original vector's placement.
rbind(vec) # illustrative
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
# vec 59 1 29 27 79 25 69 85 88 7 68 26 9 84 36
### ^^^^^^^^^^^^^^^^^^^^^^ numbers considered in first window
### ^^ results go in this position when align="right"
### ^^ results go in this position when align="center"
### ^^ results go in this position when align="left"
So looking at all three, notice where the 79 goes ... and where the NA
pad.
rbind(
vec = vec,
left = rollmax(vec, k=5, align="left", fill=NA),
center = rollmax(vec, k=5, align="center", fill=NA),
right = rollmax(vec, k=5, align="right", fill=NA)
)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
# vec 59 1 29 27 79 25 69 85 88 7 68 26 9 84 36
# left 79 79 79 85 88 88 88 88 88 84 84 NA NA NA NA
# center NA NA 79 79 79 85 88 88 88 88 88 84 84 NA NA
# right NA NA NA NA 79 79 79 85 88 88 88 88 88 84 84