From davison at stats.ox.ac.uk  Sat Apr 12 19:45:00 2008
From: davison at stats.ox.ac.uk (Dan Davison)
Date: Sat, 12 Apr 2008 18:45:00 +0100
Subject: [Rd] HOW TO AVOID LOOPS
In-Reply-To: <B57FC282-F852-432D-942F-458FA4E00ABB@act.ulaval.ca>
References: <FC1A822CDEFB4DE38EB135F6BE851F55@your136f2019dc>
	<B57FC282-F852-432D-942F-458FA4E00ABB@act.ulaval.ca>
Message-ID: <20080412174500.GA17773@stats.ox.ac.uk>

On Sat, Apr 12, 2008 at 01:30:13PM -0400, Vincent Goulet wrote:
> Le sam. 12 avr. ? 12:47, carlos martinez a ?crit :
> >> Looking for a simple, effective a minimum execution time solution.
> >>
> >> For a vector as:
> >>
> >> c(0,0,1,0,1,1,1,0,0,1,1,0,1,0,1,1,1,1,1,1)
> >>
> > To transform it to the following vector without using any loops:
> >
> >> (0,0,1,0,1,2,3,0,0,1,2,0,1,0,1,2,3,4,5,6)
> >>
> > Appreciate any suggetions.
> 
> This does it -- but it is admittedly ugly:
> 
>  > x <- c(0,0,1,0,1,1,1,0,0,1,1,0,1,0,1,1,1,1,1,1)
>  > ind <- which(x == 0)
>  > unlist(lapply(mapply(seq, ind, c(tail(ind, -1) - 1, length(x))),  
> function(y) cumsum(x[y])))
>   [1] 0 0 1 0 1 2 3 0 0 1 2 0 1 0 1 2 3 4 5 6
> 
> (The mapply() part is used to create the indexes of each sequence in x  
> starting with a 0. The rest is then straightforward.)


Here's my effort. Maybe a bit easier to digest? Only one *apply so probably more efficient.

function(x=c(0,0,1,0,1,1,1,0,0,1,1,0,1,0,1,1,1,1,1,1)) {
    d <- diff(c(0,x,0))
    starts <- which(d == 1)
    ends <- which(d == -1)
    x[x == 1] <- unlist(lapply(ends - starts, function(n) 1:n))
    x
}

Dan


> 
> HTH
> 
> ---
>    Vincent Goulet, Associate Professor
>    ?cole d'actuariat
>    Universit? Laval, Qu?bec
>    Vincent.Goulet at act.ulaval.ca   http://vgoulet.act.ulaval.ca
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] HOW TO AVOID LOOPS
Dan Davison