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.