Skip to content

Question on Reduce + rollmean

11 messages · Muhammad Rahiz, milton ruser, Gabor Grothendieck +1 more

#
Hello useRs,

I'd like to perform a moving average on the dataset, xx. I've tried 
combining the functions Reduce and rollmean but it didn't work.

 > r <- function(n) rollmean(n, 2) # where 2 = averaging interval
 > output < - Reduce("r", x)
Error in f(init, x[[i]]) : unused argument(s) (x[[i]])

Is there anything wrong with the code in the first place?

where
 > x

[[1]]
     V1 V2 V3
[1,]  1  1  1
[2,]  2  2  2
[3,]  3  3  3

[[2]]
     V1 V2 V3
[1,]  4  4  4
[2,]  5  5  5
[3,]  6  6  6

[[3]]
     V1 V2 V3
[1,]  7  7  7
[2,]  8  8  8
[3,]  9  9  9

The moving average is to be performed on

1,4,7 = (1+4)/2 , (4+7)/2
2,5,8 = ..
3,6,9 = ..

Thanks

Muhammad
#
Let me rephrase;

Given x as
[[1]]
   V1 V2 V3
[1,]  1  1  1
[2,]  2  2  2
[3,]  3  3  3

[[2]]
   V1 V2 V3
[1,]  4  4  4
[2,]  5  5  5
[3,]  6  6  6

[[3]]
   V1 V2 V3
[1,]  7  7  7
[2,]  8  8  8
[3,]  9  9  9

I'd like to calculate the moving average (interval = 2) i.e.

( x[[1]] + x[[2]] ) / 2
( x[[2]] + x[[3]] ) / 2
... and so on.

The desired output will return

2.5 2.5 2.5
3.5 3.5 3.5
4.5 4.5 4.5

5.5 5.5 5.5
6.5 6.5 6.5
7.5 7.5 7.5




Muhammad Rahiz  |  Doctoral Student in Regional Climate Modeling
Climate Research Laboratory, School of Geography & the Environment	
Oxford University Centre for the Environment, University of Oxford
South Parks Road, Oxford, OX1 3QY, United Kingdom
Tel: +44 (0)1865-285194	 Mobile: +44 (0)7854-625974
Email: muhammad.rahiz at ouce.ox.ac.uk
milton ruser wrote:
#
Try apply:

library(zoo) # rollmean

# test data
m <- matrix(1:3, 3, 3)
x <- list(m, m+3, m+6)

# convert to array
a <- array(unlist(x), c(3, 3, 3)); a

# apply rollmean and permute to desired form
aa <- apply(a, 1:2, rollmean, k = 2)
aperm(aa, c(2, 3, 1))

The last line outputs:
, , 1

     [,1] [,2] [,3]
[1,]  2.5  2.5  2.5
[2,]  3.5  3.5  3.5
[3,]  4.5  4.5  4.5

, , 2

     [,1] [,2] [,3]
[1,]  5.5  5.5  5.5
[2,]  6.5  6.5  6.5
[3,]  7.5  7.5  7.5


On Sat, Jan 2, 2010 at 10:00 AM, Muhammad Rahiz
<muhammad.rahiz at ouce.ox.ac.uk> wrote:
2 days later
#
Thanks Gabor,

It works alright. But is there alternative ways to perform rollmean 
apart from permutating the data?
Possibly combining the Reduce and rollmean functions?

The easiest but traditional way is

 > (x[[1]]+x[[2]]) / 2
 > (x[[2]]+x[[3]]) / 2
 

Muhammad Rahiz  |  Doctoral Student in Regional Climate Modeling					
Climate Research Laboratory, School of Geography & the Environment	
Oxford University Centre for the Environment
South Parks Road, Oxford, OX1 3QY, United Kingdom 
Tel: +44 (0)1865-285194	 Mobile: +44 (0)7854-625974
Email: muhammad.rahiz at ouce.ox.ac.uk
Gabor Grothendieck wrote:
#
This is due to the non-idempotent nature of apply.  Instead of apply,
you can use

- aaply in the plyr package
     http://tolstoy.newcastle.edu.au/R/devel/06/06/5687.html

- or the idempotent apply (iapply) posted here by Hadley Wickham:

and in either case you won`t have to permute the result.

On Mon, Jan 4, 2010 at 10:54 AM, Muhammad Rahiz
<muhammad.rahiz at ouce.ox.ac.uk> wrote:
#
For this example try this:

lapply(lapply(list('head', 'tail'), do.call, list(x, n = -1)),
function(x)Reduce('+', x)/2)


On Mon, Jan 4, 2010 at 1:54 PM, Muhammad Rahiz
<muhammad.rahiz at ouce.ox.ac.uk> wrote:

  
    
#
Here is a variation which also uses head and tail:

mapply(function(x, y) (x + y)/2, tail(x, -1), head(x, -1), SIMPLIFY = FALSE)
On Mon, Jan 4, 2010 at 12:37 PM, Henrique Dallazuanna <wwwhsd at gmail.com> wrote:
2 days later
#
Dear Gabor & Henrique,

Thanks for your suggestions on the above problem. The following is more traditional and unfanciful but it works. Suitable for a prodige like myself...

m <- matrix(1:3,3,3)
x1 <- list(m, m+1, m+2, m+3, m+4) 

out <- list()
for (i in 1:4){
t[[i]] <- Reduce("+", x1[c(i:i+1)])
}

Muhammad

Muhammad Rahiz  |  Doctoral Student in Regional Climate Modeling					
Climate Research Laboratory, School of Geography & the Environment	
Oxford University Centre for the Environment
South Parks Road, Oxford, OX1 3QY, United Kingdom 
Tel: +44 (0)1865-285194	 Mobile: +44 (0)7854-625974
Email: muhammad.rahiz at ouce.ox.ac.uk
Gabor Grothendieck wrote:
#
That gives an error when I run it.  I think you want this:

m <- matrix(1:3,3,3)
x1 <- list(m, m+1, m+2, m+3, m+4)

out <- list()
for(i in 1:4) out[[i]] <- (x1[[i]] + x1[[i+1]]) / 2


On Thu, Jan 7, 2010 at 12:28 PM, Muhammad Rahiz
<muhammad.rahiz at ouce.ox.ac.uk> wrote:
#
Yes, should be
1. out[[i]], instead of t[[i]].
2. x1[c(i:(i+1))]  # For this case, I was trying out the rolling sum.

Muhammad Rahiz  |  Doctoral Student in Regional Climate Modeling					
Climate Research Laboratory, School of Geography & the Environment	
Oxford University Centre for the Environment
South Parks Road, Oxford, OX1 3QY, United Kingdom 
Tel: +44 (0)1865-285194	 Mobile: +44 (0)7854-625974
Email: muhammad.rahiz at ouce.ox.ac.uk
Gabor Grothendieck wrote: