Skip to content
Prev 4050 / 398506 Next

Combinations

On Mon, 13 Dec 1999, a s wrote:

            
There is code to do that in Venables & Ripley, called subsets. Here's
a later version (from our forthcoming `S Programming' book)

subsets <- function(n, r, s = 1:n) {
  if(mode(n) != "numeric" || length(n) != 1
     || n < 1 || (n %% 1) != 0) stop("bad value of n")
  if(mode(r) != "numeric" || length(r) != 1
     || r < 1 || (r %% 1) != 0) stop("bad value of r")
  if(!is.atomic(s) || length(s) < n)
    stop("s is either non-atomic or too short")
  fun <- function(n, r, s)
    if(r <= 0) vector(mode(s), 0) else if(r >= n) s[1:n] else
    rbind(cbind(s[1], Recall(n - 1, r - 1, s[-1])),
          Recall(n - 1, r, s[-1]))
  fun(n, r, s)
}

Use it by

subs <- function(x, string)
  subsets(length(string), x, string)


You will need quotes! Actually, this will work for any (atomic) mode of
vector. If you have long strings,

subs <- function(x, string)
{ 
  z <- subsets(length(string), x)
  zz <- string[as.vector(z)]
  dim(zz) <- dim(z)
  zz
} 

might be better.