[R] How do I avoid a loop?
Gabor Grothendieck
ggrothendieck at gmail.com
Tue Jun 19 16:44:12 CEST 2007
Here is a slight variation. The second line is unchanged from my
prior solution but the first line is different. The previous one I posted
was slightly more complex and took about 50% longer to run than
this one:
xx <- (cumsum(!x) + 1) * x
(seq_along(x) - match(xx, xx) + 1) * x
> # performance testing
>
> f1 <- function(x) {
+ xx <- cumsum(diff(c(FALSE, x)) > 0)
+ (seq_along(x) - match(xx, xx) + 1) * x
+ }
>
> f2 <- function(x) {
+ xx <- (cumsum(!x) + 1) * x
+ (seq_along(x) - match(xx, xx) + 1) * x
+ }
>
>
> f3 <- function(x) {
+ j <- 0
+ for(i in seq_along(x)) x[i] <- if (x[i]) j <- j+1 else j <- 0
+ x
+ }
>
> set.seed(1)
> x <- sample(c(TRUE, FALSE), 100000, replace = TRUE)
> system.time(out1 <- f1(x))
user system elapsed
0.10 0.02 0.12
> system.time(out2 <- f2(x))
user system elapsed
0.07 0.01 0.08
> system.time(out3 <- f3(x))
user system elapsed
1.65 0.00 1.72
> identical(out1, out2)
[1] TRUE
> identical(out1, out3)
[1] TRUE
On 6/19/07, Gabor Grothendieck <ggrothendieck at gmail.com> wrote:
> xx is 1 in every position of the first run of TRUE, 2 in every
> position in the 2nd run of TRUE and so on. The parenthesized
> expression in the second line converts those to increasing
> values and multiplying it by x zaps the garbage in the positions
> that correspond to FALSE in x.
>
> xx <- cumsum(diff(c(FALSE, x)) > 0)
> (seq_along(x) - match(xx, xx) + 1) * x
>
>
> On 6/19/07, Feng, Ken <ken.feng at citi.com> wrote:
> > Hi,
> >
> > I start with an array of booleans:
> >
> > x <- c( TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE );
> >
> > I want to define an y <- f(x) such that:
> >
> > y <- c( 1, 2, 3, 0, 0, 1, 2, 0, 1 );
> >
> > In other words, do a cumsum when I see a TRUE, but reset to 0 if I see a FALSE.
> >
> > I know I can do this with a very slow and ugly loop or maybe use apply,
> > but I was hoping there are some R experts out there who can show me
> > a cleaner/more elegant solution?
> >
> > Thanks in advance.
> >
> > - Ken
> >
> > ______________________________________________
> > R-help at 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.
> >
>
More information about the R-help
mailing list