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 ______________________________________________ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.