Sumit
Sumit

Reputation: 2250

How to calculate average of every three consecutive elements

Here is a list.

 1 2 3 4 5 6 7 8 9 10. 

I would like to calculate average of every three consecutive elements. For instance, output would be NA NA 2 3 4 5 6 7 8 9.

How to do this?

Regards

Upvotes: 2

Views: 1950

Answers (3)

Matthew Plourde
Matthew Plourde

Reputation: 44614

This is fourth way, using the lag function:

v <- 1:10
rowMeans(do.call(cbind, lapply(0:2, lag, x=as.ts(v))))
# [1] NA NA  2  3  4  5  6  7  8  9 NA NA

You can wrap this in na.omit to remove the NAs.

Benchmarks

library(microbenchmark)
library(zoo)
v <- 1:10000
f.embed <- function() rowMeans(embed(v, 3))
f.filter <- function() filter(x=v, filter=rep(1/3, 3), sides=1)
f.lag <- function() rowMeans(do.call(cbind, lapply(0:2, lag, x=as.ts(v))))
f.rollmean <-function() rollapply(v, width=3, align="right", FUN=mean, fill=NA ) 
microbenchmark(f.embed(), f.filter(), f.lag(), f.rollmean())
# Unit: microseconds
#          expr    min     lq median     uq     max neval
#     f.embed()  486.7  499.8  505.6  517.1  1633.1   100
#    f.filter()  285.3  300.7  307.2  316.6   912.5   100
#       f.lag() 1601.6 1640.9 1677.0 2188.3  2838.7   100
#  f.rollmean() 4265.4 4853.5 4902.0 5364.8 52098.9   100

Upvotes: 3

Jilber Urbina
Jilber Urbina

Reputation: 61164

You can even use either rollapply or rollmean from zoo package

> library(zoo)
> v <- 1:10
> rollapply(v, width=3, align="right", FUN=mean, fill=NA )
 [1] NA NA  2  3  4  5  6  7  8  9

> rollmean(v, k=3, align="right",  fill=NA )
 [1] NA NA  2  3  4  5  6  7  8  9

Upvotes: 6

sgibb
sgibb

Reputation: 25736

You could try ?embed and ?rowMeans:

v <- 1:10

m <- embed(v, 3)
m
#    [,1] [,2] [,3]
#[1,]    3    2    1
#[2,]    4    3    2
#[3,]    5    4    3
#[4,]    6    5    4
#[5,]    7    6    5
#[6,]    8    7    6
#[7,]    9    8    7
#[8,]   10    9    8

rowMeans(m)
# 2 3 4 5 6 7 8 9

EDIT: Another solution would be ?filter:

filter(x=v, filter=rep(1/3, 3), sides=1)
# Time Series:
# Start = 1 
# End = 10 
# Frequency = 1 
#  [1] NA NA  2  3  4  5  6  7  8  9

Upvotes: 9

Related Questions