[18912] in s-news-athena
[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