[R] How to optimize this loop ? (correction)
Berwin A Turlach
statba at nus.edu.sg
Fri Jan 19 04:13:29 CET 2007
G'day Martin and others,
On Thu, 18 Jan 2007 15:22:07 +0100
Martin Becker <martin.becker at mx.uni-saarland.de> wrote:
> Sorry, I accidentaly lost one line of the function code (result <-0),
> see below...
But even with that line, the code doesn't work properly. :)
Since you changed the order of the for loop (from "i in 1:(len-1)" to
"i in (len-1):1") you broke the logic of the code and the result
returned is wrong (should be something like "result <- len-i" instead
of "result <- i-1").
I agree that your function is faster than the one based on rle(),
presumably because rle() does just too many additional computations
that are not necessary to solve the problem at hand. But I still don't
like to see for() loops in R code. :) I would suggest the following
solution (which is only marginally slower than yours on these example
inputs):
myfun2 <- function(x){
len <- length(x)
which.max(c(x[len] <= rev(x[-len]), TRUE) ) - 1
}
The concatenation of TRUE at the end of the logical vector is necessary
for the case that all elements before the last are smaller than the
last one. It also has the side benefit that myfun(2) will return 0
instead of numeric(0) (or something similar). On my machine:
> system.time(for (i in 1:10000) erg<-my_fun(c(3, 4, 10,14,8,3,4,6,9)))
[1] 2.860 0.016 2.950 0.000 0.000
> system.time(for (i in 1:10000) erg<-myfun1(c(3, 4, 10,14,8,3,4,6,9)))
[1] 0.256 0.000 0.256 0.000 0.000
> system.time(for (i in 1:10000) erg<-myfun2(c(3, 4, 10,14,8,3,4,6,9)))
[1] 0.280 0.000 0.283 0.000 0.000
Cheers,
Berwin
=========================== Full address =============================
Berwin A Turlach Tel.: +65 6515 4416 (secr)
Dept of Statistics and Applied Probability +65 6515 6650 (self)
Faculty of Science FAX : +65 6872 3919
National University of Singapore
6 Science Drive 2, Blk S16, Level 7 e-mail: statba at nus.edu.sg
Singapore 117546 http://www.stat.nus.edu.sg/~statba
More information about the R-help
mailing list