[R] avoiding a loop
Ray Brownrigg
Ray.Brownrigg at mcs.vuw.ac.nz
Fri Oct 27 05:17:28 CEST 2006
On Wednesday 25 October 2006 07:36, Leeds, Mark (IED) wrote:
> I think I asked a similar question 3 years ago to the Splus list and I
> think the answer was no or noone answered so noone should spend more
> than 5 minutes on this
> because it could definitely be a waste of time.
>
> My question is whether the function below can be rewritten without a for
> loop. apply is fine if it can be done that way but i doubt it. I call it
> a lot and would
> prefer to not loop.
>
> #-----------------------------------------------------------------------
> --------------------------
>
> constructLt<-function(invector) {
>
> outvector<-invector
>
> for ( i in 2:length(invector) ) {
> if ( invector[i] < 1 ) {
> outvector[i]<-invector[i]*outvector[i-1]
> }
> }
>
> return(outvector)
>
> }
>
Depending on the nature of your data, there is a faster way. It still
involves looping, but not over the entire vector.
Try the following:
constructLt <- function(invector) {
outvector <- invector
cs <- cumsum(rle(invector < 1)$lengths)
if (invector[1] < 1)
cs <- c(1, cs)
for (i in 0:(length(cs)%/%2 - 1)){
starti <- cs[2*i + 1]
stopi <- cs[starti + 1]
outvector[starti:stopi] <- cumprod(invector[starti:stopi])
}
return(outvector)
}
It is in the order of 3 times as fast for random vectors of considerable
length (> 1000). For random vectors of length 50 it is about the same speed
as the full looping algorithm. However if the data is such that there are
longer runs (than N(1, 1)), then you might expect a better speedup.
HTH
Ray Brownrigg
More information about the R-help
mailing list