I had a bug in my last solution.
This one should work.

next.combin <- function(oldcomb,n){
  lcomb <- length(oldcomb)
  hole.pos <- last.hole.pos(oldcomb,n)
  if ((hole.pos == lcomb) & oldcomb[lcomb]==n) {
    return(NA)
  }
  newcomb<-oldcomb
  newcomb[hole.pos:lcomb]<-oldcomb[hole.pos]+(1:(lcomb-hole.pos+1))  
  return(newcomb)
}

last.hole.pos <- function(comb,n){
 lcomb <- length(comb)
 if (comb[lcomb]<n) {
   return(lcomb)
 }
 diffs <- comb[-1]-comb[-lcomb]
 if (max(diffs)==1) {
        return(lcomb)
 } 
 diffpos <- which(diffs>1)
 return(diffpos[length(diffpos)])  
}

demo <- function(n,k){
  currCombin <- 1:k 
  #this is the first possible combination k out if n. 
  selectedSet <- NULL
  while (!any(is.na(currCombin))){
#  if(currCombin passes test) {
     selectedSet <- rbind(selectedSet,currCombin)
#  }
  currCombin <- next.combin(currCombin,n)
  }
  rownames(selectedSet)<-NULL
  selectedSet
}

On Mar 6, 2010, at 9:50 PM, Herm Walsh wrote:

> The usage here is exactly what I am looking for, thanks.  However this 
> function seems to omit some combinations.  Continuing with the example below, 
> given an always true condition in #***, it will only produce 7 combinations 
> (omitting 1,5 1,4 and 2,5).
> Am I overlooking something that makes it produces all of the combinations?
> 
>  
> 
> From: Erich Neuwirth <erich.neuwi...@univie.ac.at>
> To: Herm Walsh <hermwa...@yahoo.com>; r-help <r-help@r-project.org>
> Sent: Sat, March 6, 2010 9:12:13 AM
> Subject: Re: [R] Working with combinations
> 
> currCombin <- c(1,2) #this is the first possible combination 2 out if 5. 
> Since the vector has length 2, we are doing 2 out of x here.
> selectedSet <- NULL
> while (!is.na(currCombin)){
>    if( #*** currCombin passes test ***#   ) {
>       selectedSet <- rbind(selectedSet,currCombin)
>    }
>  currCombin <- next.combin(currCombin,5) #here we say that we want 2 out of 5
>  }
> 
> 
> 
> On Mar 6, 2010, at 5:54 PM, Herm Walsh wrote:
> 
>> Erich-
>> This approach would be great for my context.  However, in the code below I 
>> do not see how to restrict the output to the set of combinations I am 
>> looking for.  For example, suppose I am looking for the 10 two element 
>> combinations of 1:5.  Can you give me some psuedocode that shows how to do 
>> this?
>> After putting the code below in a loop I do not see how to restrict the 
>> output to containing only numbers from 1:5.
>> thanks very much.
>> 
>> From: Erich Neuwirth <erich.neuwi...@univie.ac.at>
>> To: Herm Walsh <hermwa...@yahoo.com>
>> Cc: David Winsemius <dwinsem...@comcast.net>; r-help@r-project.org
>> Sent: Wed, March 3, 2010 2:10:34 PM
>> Subject: Re: [R] Working with combinations
>> 
>> The following code takes a combination of type n over k represented by an 
>> increasing sequence
>> as input an produces the lexicographically next combinations.
>> So you can single step through all possible combinations and apply your 
>> filter criteria
>> before you produce the next combination.
>> 
>> 
>> next.combin <- function(oldcomb,n){
>>    lcomb <- length(oldcomb)
>>    hole.pos <- last.hole.pos(oldcomb,n)
>>    if ((hole.pos == lcomb) & oldcomb[lcomb]==n) {
>>      return(NA)
>>    }
>>    newcomb<-oldcomb
>>    newcomb[hole.pos]<-oldcomb[hole.pos]+1
>>    return(newcomb)
>> }
>> 
>> last.hole.pos <- function(comb,n){
>>   lcomb <- length(comb)
>>   diffs <- comb[-1]-comb[-lcomb]
>>   if (max(diffs)==1) {
>> return(lcomb)
>>   } 
>>   diffpos <- which(diffs>1)
>>   return(diffpos[length(diffpos)])  
>>    
>> }
>> 
>> On Mar 3, 2010, at 7:35 PM, Herm Walsh wrote:
>> 
>>> Thanks David for the thoughts.  The challenge I have with this approach is 
>>> that the criteria I have is defined by a series of tests--which I do not 
>>> think I could substitute in in place of the logical indexing.
>>> 
>>> In the combinations code I was hoping there is a step where, each new 
>>> combination is added to the current list of combinations.  If this were the 
>>> case, I could put my series of tests in the code right there and then store 
>>> the combination if appropriate.
>>> 
>>> However, evalutating the code--which uses recursion--I am not sure if this 
>>> approach will work.  The combinations code is listed below.  Is there a 
>>> simple place(s) where I could insert my tests, operating on the current 
>>> combination?
>>> 
>>> function (n, r, v = 1:n, set = TRUE, repeats.allowed = FALSE) 
>>> {
>>>     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(v) || length(v) < n) 
>>>         stop("v is either non-atomic or too short")
>>>     if ((r > n) & repeats.allowed == FALSE) 
>>>         stop("r > n and repeats.allowed=FALSE")
>>>     if (set) {
>>>         v <- unique(sort(v))
>>>         if (length(v) < n) 
>>>             stop("too few different elements")
>>>     }
>>>     v0 <- vector(mode(v), 0)
>>>     if (repeats.allowed) 
>>>         sub <- function(n, r, v) {
>>>             if (r == 0) 
>>>                 v0
>>>             else if (r == 1) 
>>>                 matrix(v, n, 1)
>>>             else if (n == 1) 
>>>                 matrix(v, 1, r)
>>>             else rbind(cbind(v[1], Recall(n, r - 1, v)), Recall(n - 
>>>                 1, r, v[-1]))
>>>         }
>>>     else sub <- function(n, r, v) {
>>>         if (r == 0) 
>>>             v0
>>>         else if (r == 1) 
>>>             matrix(v, n, 1)
>>>         else if (r == n) 
>>>             matrix(v, 1, n)
>>>         else rbind(cbind(v[1], Recall(n - 1, r - 1, v[-1])), 
>>>             Recall(n - 1, r, v[-1]))
>>>     }
>>>     sub(n, r, v[1:n])
>>> }
>>> <environment: namespace:gtools>
>>> 
>>> 
>>> 
>>> **************************************************************************************************************************************************************
>>> 
>>>> I am working with the combinations function (available in the gtools 
>>>> package).  However, rather than store all of the possible combinations I 
>>>> would like to check each combination to see if it meets a certain 
>>>> criteria.  If it does, I will then store it.
>>>> 
>>>> I have looked at the combinations code but am unsure where in the 
>>>> algorithm I would be able to operate on each combination.
>>> 
>>> Logical indexing:
>>> 
>>>> combinations(3,2,letters[1:3])[,1]=="a"
>>> [1]  TRUE  TRUE FALSE
>>> 
>>>> combinations(3,2,letters[1:3])[ combinations(3,2,letters[1:3])[,1]=="a", ]
>>>     [,1] [,2]
>>> [1,] "a"  "b"
>>> [2,] "a"  "c"
>>> 
>>> --David 
>>> 
>>> 
>>> 
>>> 
>>> [[alternative HTML version deleted]]
>>> 
>>> ______________________________________________
>>> R-help@r-project.org 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.
>> 
>> --
>> Erich Neuwirth
>> Didactic Center for Computer Science and Institute for Scientific Computing
>> University of Vienna
>> 
>> 
>> 
>> 
>> 
>> 
> 
> --
> Erich Neuwirth
> Didactic Center for Computer Science and Institute for Scientific Computing
> University of Vienna
> 
> 
> 
> 
> 
> 

--
Erich Neuwirth
Didactic Center for Computer Science and Institute for Scientific Computing
University of Vienna





        [[alternative HTML version deleted]]

______________________________________________
R-help@r-project.org 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.

Reply via email to