[18795] in s-news-athena

home help back first fref pref prev next nref lref last post

Re: [S] Help eliminate a recursive function

daemon@ATHENA.MIT.EDU (Bill Venables)
Fri Jul 30 03:06:54 1999

Date: Fri, 30 Jul 1999 16:55:44 +1000 (EST)
Message-Id: <199907300655.QAA17061@acland.qld.cmis.CSIRO.AU>
From: Bill Venables <venables@acland.qld.cmis.csiro.au>
To: moord@email.uc.edu
Cc: S-news@wubios.wustl.edu
Reply-To: Bill.Venables@cmis.csiro.au


David,

Doing things in a loop can be rather costly in S, too, but if you
need to generate all possible subsets sequentially here is *one*
way to do it.

(Code below; figuring out how it works, and improving it, remains
an exercise for the casual onlooker.)

It returns the next subset at each call, and NULL when the
sequence is finished.  Here is an example of how you might use it:

> while(!is.null(m <- next.subset(5, 3))) 
  {
	#  `m' holds the index of the subset
        print(m)
  }
[1] 1 2 3
[1] 1 2 4
[1] 1 2 5
[1] 1 3 4
[1] 1 3 5
[1] 1 4 5
[1] 2 3 4
[1] 2 3 5
[1] 2 4 5
[1] 3 4 5
> 

(Instead of "print(m)" you may wish to do something more
interesting...)

---(cut here)---
next.subset <- function(n, r) {
  if(exists(NR <- paste(n, r), frame = 0)) {
    nr <- get(NR, frame = 0)
    if(any(w <- (nr < (n-r+1):n))) {
      m <- max((1:r)[w])
      k <- m:r
      nr[k] <- k + nr[m] - m + 1
    }
    else {
      remove(NR, frame = 0)
      return(NULL)
    }
  }
  else
    nr <- 1:r
  assign(NR, nr, frame = 0)
  nr
}

cancel <- function(n, r)
  invisible(if(exists(nr <- paste(n, r), frame = 0))
            remove(nr, frame = 0))
---(cut here)---

If you wish to re-start the sequence you should use the function

> cancel(5, 3)

to go back to the beginning.

The function is just a way of presenting an algorithm.  If you
really are committed to using a very long loop in S code, you
probably should build in the next.subset computation as part of
the loop rather than calling a function every time, but there may
not be very much in it, especially if each step is going to be a
pretty large computation, anyway.  This is the sort of territory
where dynamically loaded code starts to become unavoidable.

-- 
-----------------------------------------------------------------
Bill Venables, Statistician, CMIS Environmetrics Project.

Physical address:                            Postal address:
CSIRO Marine Laboratories,                   PO Box 120,       
233 Middle St, Cleveland, Queensland         Cleveland, Qld, 4163
AUSTRALIA                                    AUSTRALIA

Telephone: +61 7 3826 7251     Email: Bill.Venables@cmis.csiro.au     
      Fax: +61 7 3826 7304
-----------------------------------------------------------------------
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

home help back first fref pref prev next nref lref last post