Question

[Solved] How to calculate 7-day moving average in R?

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 put “right”, “center” or “left” it changes the values. What’s the difference between them?

Example code:

test <- sample(1:50)
data <- rollmean(test, 7, fill = list(NA, NULL, NA), align = "right")

test <- cbind(test, data)

Solution #1:

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
Respondent: Ian Campbell

Solution #2:

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".

Respondent: G. Grothendieck

Solution #3:

?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
Respondent: r2evans

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Most Popular

To Top
India and Pakistan’s steroid-soaked rhetoric over Kashmir will come back to haunt them both clenbuterol australia bossier man pleads guilty for leadership role in anabolic steriod distribution conspiracy