[18912] in s-news-athena

home help back first fref pref prev next nref lref last post

[S] summary: rewrite a loop

daemon@ATHENA.MIT.EDU (fan@katan.cybercom.net)
Tue Aug 10 19:13:12 1999

From: fan@katan.cybercom.net
Date: Tue, 10 Aug 1999 19:05:11 -0400
Message-Id: <199908102305.TAA05152@katan.cybercom.net>
To: fangc@stat.cmu.edu, s-news@wubios.wustl.edu


To summarize the answers: function filter() is specifically for computing
moving average. In addition, a method with matrix operation and a longer 
method with double apply() are also sent in. Details:

1.filter() (Bill Dunlap, Richard Raubertas)
  
  The outputs of filter() needs a bit explicit casting because it assumes the
  input is a time series.

  x <- 1:1000
  y <- as.vector(filter(x,filter=rep(1/30,30)))
  y <- y[y!="NA"]

2.matrix operation (Rolf Turner)
In R, the one line below actually works well. Also, plain R does not have 
filter(). 

Rolf Turner <rolf@math.unb.ca> writes:

[begin]
options(warn=-1) # Suppress annoying warning message.
y <- apply(matrix(x,nrow=1001,ncol=30)[1:971,],1,mean)
options(warn=0)  # Restore warnings.

This code does what you want without an explicit for loop.  But it
takes substantially ***more*** time on my machine (Sparc 20 under
Solaris 2.5, Splus 3.4):

        2.03 seconds without the loop as opposed to
        0.13 seconds with the loop.

Sometimes loops are better.
[end]

3.double apply (by Fang Chen)
The codes below takes a while to read, but it answers the question of "how
not to use loop". :)

[begin]
seq.fun_function(vec)
{
        x <- vec[1]
        y <- vec[2]
        z <- x:y
        return(z)
}  

x_rnorm(1000)
x1_1:30
x2_971:1000
tmp_apply(cbind(x1, x2), 1, seq.fun)
y1_apply(matrix(x[t(tmp)], nrow=30), 2, mean)
[end]


----------------
> From: fan@katan.cybercom.net
> Date: Tue, 10 Aug 1999 15:54:04 -0400
> To: s-news@wubios.wustl.edu
> Subject: [S] rewrite a loop
> X-loop: s-news
> 
> 
> In computing a moving average of a sequence, I look for a way not to use
> the loop? Example:
> 
> #x is a sequence of 1000 data points
> x<-1:1000
> #y is the 30-term moving average of x; 
> #i.e.: y[i] <- mean(x[i:(i+29)]), i = 1, ..., 971
> #or in vector form: y <- (x[1:971]+x[2:972]+...+x[30:1000])/30
> #Surely, a loop solves it:
> y <- rep(0,length(x)-30+1)
> for (j in 1:30)
>     y <- y + x[i:(i+970)]
> y <- y/30
> 
> I feel some better codes can work on this job efficiently without using loop. 
> If you have an idea, let me know. Thanks.
> 
> Fan







-----------------------------------------------------------------------
This message was distributed by s-news@wubios.wustl.edu.  To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message:  unsubscribe s-news

home help back first fref pref prev next nref lref last post