0

I have used rollmean in R to calculate a moving average as so:

> x = c(3, 8, 12, 5, 9, 6, 8)
> rollmean(x, 7)
[1] 7.285714

Rollmean takes an odd number input and calculates the Moving Average, INCLUSIVE of the middle value (in this case 5). However I would like to know if there is a function that allows for calculating the MA around a value, EXCLUDING it, so as to assess the impact around the middle value. Using this example, the average of 3+8+12+9+6+8, not including the middle value 5.

My preference is to avoid having to write a complex function if there is something available.

Thanks!

Qaribbean
  • 178
  • 2
  • 3
  • 17

1 Answers1

1

You can use rollapply (which allows you to apply a custom function to a rolling window) and write a simple function to exclude the middle value. For example:

my_mean = function(x) {
  if(length(x) %% 2 == 0L) { return(mean(x)) }
  if(length(x) %% 2 == 1L) { return(mean(x[-ceiling(0.5*length(x))])) }
}

# Fake data
set.seed(5)
values = cumsum(rnorm(20))

library(zoo)

rollapply(values, width=5, FUN=my_mean)
[1]  0.032599697  0.341949790 -0.223156076 -0.054644590 -0.007797604 -0.313482549 -0.248932331 -0.372755845
[9] -0.880215212 -0.848262308 -1.049123185 -1.822352744 -2.315909292 -3.318552855 -4.107026776 -4.295736122
eipi10
  • 91,525
  • 24
  • 209
  • 285
  • Thanks @eipi10, I thought having to create a function might be the case. Running your example in R works fine, I gathered that the `width` in roll apply provides the window and middlevalue to be used. Would you mind briefly explaining the two IF statements, just so I can better understand the function you wrote, thank you. – Qaribbean Apr 14 '16 at 10:07
  • Yes, `width` is the window size. The `if` statements check whether `width` is even or odd. `length(x) %% 2` returns the remainder after division by 2. – eipi10 Apr 14 '16 at 14:51