I have a data frame of time-series prices and I want a new column within the data frame which is the average of the previous 10 observations of the prices. Therefore this new variable must start in row 10 and be rolling, i.e. observation 10 is the average of the previous 10 prices (observations 1-10), observation 11 is the average of the previous 10 prices (observations 2-11) and so on.
Asked
Active
Viewed 100 times
-1
-
1Try looking on "moving average", so you find questions like these: http://stackoverflow.com/questions/743812/calculating-moving-average-in-r – Joris Meys Oct 22 '14 at 09:05
-
Or try library(gtools), running() function: e.g. running(data, width=10, pad=TRUE, fun=mean). ?running – KFB Oct 22 '14 at 09:06
-
Welcome on SO by the way. People are always willing to help, but you have to do at least a bit of effort trying to solve the problem first. There's plenty of information on rolling averages. So try something out first, and if you can't get it to work, give us a reproducible example and what you want to achieve, and we'll be happy to help you. http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – Joris Meys Oct 22 '14 at 09:07
4 Answers
1
Use running()
from gtools
package:
#dummy data
set.seed(123)
df <- data.frame(x=round(runif(12,1,10)))
require(gtools)
#get running mean starting on 10th row
df$RunningMean <- running(df$x,width = 10,pad=TRUE)
df
#output
x RunningMean
1 4 NA
2 8 NA
3 5 NA
4 9 NA
5 9 NA
6 1 NA
7 6 NA
8 9 NA
9 6 NA
10 5 6.2
11 10 6.8
12 5 6.5
Or if you prefer to use gtools and dplyr together. The same result.
library(gtools); library(dplyr)
df <- data.frame(x=round(runif(12,1,10)))
df %>% mutate(RunningMean = running(x, width=10, pad=TRUE, fun=mean))

KFB
- 3,501
- 3
- 15
- 18
1
Or simply use filter
which allows you to do that without loading extra packages :
set.seed(123)
df <- data.frame(x=round(runif(12,1,10)))
n <- 10
df <- within(df,{
runmean <- filter(x,rep(1/n,n), sides=1)
})
Another tip: if you want to do that within a data frame and you don't want to be typing those dollar signs the whole time, use the convenient function within()
as I did in the example. Don't forget to put the argument sides=1
, otherwise you'll take the mean centered around the value you're at (which is the default).

Joris Meys
- 106,551
- 31
- 221
- 263
1
You could use zoo
(Using @KFB's example). Using the align
argument, you can specify left
, right
or center
for the NAs
to occupy.
library(zoo)
rollmean(df$x, k=10,na.pad=TRUE, align="right")
#[1] NA NA NA NA NA NA NA NA NA 6.2 6.8 6.5

akrun
- 874,273
- 37
- 540
- 662
-1
#the first 9 rows are blank
for (i in 1:9)
{
average[i]=NA
}
for (i in 1:(length(prices)-9))
{
average[i+9]=mean(prices[i:(i+9)])
}

george
- 84
- 2
-
1There is quite a few things problematic. First of all, don't grow vectors in R, that's slow and hell for your memory. Second, there are vectorized solutions available in R so there's no need to implement it yourself. Third, if you want to do it yourself, wrap everything in a function so it doesn't change things in your global workspace. – Joris Meys Oct 22 '14 at 09:09