Re: [S] Looping

Bill Venables (wvenable@attunga.stats.adelaide.edu.au)
Fri, 21 Aug 1998 18:03:12 +0930


: Is there a way to avoid the loops below?
: vec is a vector of length n. I want to count the number of instances
: where an element and the next j-th element both equals 1.
:
: n <- length (vec)
: aaa <- rep (0, n)
: for (j in 0:(n-1)){
: aa <- 0
: for (i in 1:(n - j)){
: if ( vec[i] == 1 & vec[i+j] == 1 ) aa <- aa + 1
: }
: aaa[j+1] <- aa
: }
:
: For example:
: > vec <- c(1,0,1,1,2,1,2,1,0,1)
: yields
: > aaa
: [1] 6 1 4 2 2 2 1 2 0 1

You can remove one level of looping at least, for example

> a <- rep(0, l <- length(vec))
> x1 <- x2 <- vec == 1
> for(i in 1:l) {
+ a[i] <- sum(x1*x2)
+ x1 <- x1[-length(x1)]
+ x2 <- x2[-1]
+ }
> a
[1] 6 1 4 2 2 2 1 2 0 1

Formally you can appear to remove looping altogether with
something like

> x <- vec == 1
> m <- outer(x, x)
> a <- tapply(m, row(m) - col(m), sum)[-(1:(length(vec)-1))]
> as.vector(a)
[1] 6 1 4 2 2 2 1 2 0 1

but if vec is a longish vector, the greater memory use of the
second may mean it is impractical.

I would tend to recommend the single loop solution as the best
compromise in most situations. It is simply not true that loops
are always a killer and to be avoided at absolutely all costs.

Bill Venables.

-- 
_________________________________________________________________
Bill Venables, Head, Dep't of Statistics,     Tel.: +61 8303 5418
The University of Adelaide,                   Fax.: +61 8303 3696
South AUSTRALIA.     5005.   Email: Bill.Venables@adelaide.edu.au
-----------------------------------------------------------------------
This message was distributed by s-news@wubios.wustl.edu.  To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message:  unsubscribe s-news