简体   繁体   中英

R find all possible unique combinations

I am trying to find all possible unique combinations in R. It seems that there have been a lot of similar questions asked, but I was not able to find the same one.

My question is to find combinations of m number of elements from vector x, but m could be larger than x. For example, pick 3 elements from letters[1:2], which hopefully can return:

combn(letters[1:2],3)
       [,1]  [,2]  [,3]  [,4] 
[1,]   "a"   "a"   "a"    "b"
[2,]   "a"   "a"   "b"    "b"
[3,]   "a"   "b"   "b"    "b"

But instead error in combn function n < m. There are similar functions including gtools:permutations, expand.grid.

Apologize again if someone asked the same questions previously, but I did not catch it. Thanks.

There are a few packages specifically built for this. The basic premise is that we need combinations with repetition of length m where m could be larger than the input vector. We start with the classic gtools :

library(gtools)
combinations(2, 3, letters[1:2], repeats.allowed = TRUE)
    [,1] [,2] [,3]
[1,] "a"  "a"  "a" 
[2,] "a"  "a"  "b" 
[3,] "a"  "b"  "b" 
[4,] "b"  "b"  "b"

And then there is arrangements which is a replacement for iterpc (the package linked by @Gregor in the comments above):

library(arrangements)
arrangements::combinations(2, 3, letters[1:2], replace = TRUE)
     [,1] [,2] [,3]
[1,] "a"  "a"  "a" 
[2,] "a"  "a"  "b" 
[3,] "a"  "b"  "b" 
[4,] "b"  "b"  "b"

And finally there is RcppAlgos , which I authored:

library(RcppAlgos)
comboGeneral(letters[1:2], 3, TRUE)
     [,1] [,2] [,3]
[1,] "a"  "a"  "a" 
[2,] "a"  "a"  "b" 
[3,] "a"  "b"  "b" 
[4,] "b"  "b"  "b"

combn is an awesome function that ships as one of the base packages with R , however one of its shortcomings is that it doesn't allow repetition (which is what is required here). I wrote a pretty comprehensive overview for problems exactly like this one that can be found here: A Walk Through a Slice of Combinatorics in R .

combn1=function(x,m){
  n=ifelse(length(x)==1,ifelse(is.numeric(x),x,1),length(x))
  if(n>=m) return(combn(x,m))
  a=do.call(expand.grid, rep(list(x),m))
  b=t(unique(t(apply(a,1,sort))))
  `dimnames<-`(b,NULL)
}

combn1(letters[1],3)
     [,1]
[1,] "a" 
[2,] "a" 
[3,] "a" 
> combn1(letters[1:2],3)
     [,1] [,2] [,3] [,4]
[1,] "a"  "a"  "a"  "b" 
[2,] "a"  "a"  "b"  "b" 
[3,] "a"  "b"  "b"  "b" 
> combn1(letters[1:3],3)
     [,1]
[1,] "a" 
[2,] "b" 
[3,] "c" 

This maybe worked, which list all the unique combinations without repeat

> v1 = letters[1:4]
> v1 
[1] "a" "b" "c" "d"

> do.call("c",lapply(seq_along(v1),function(i) utils::combn(v1,i,FUN=list)))


[[1]]
[1] "a"

[[2]]
[1] "b"

[[3]]
[1] "c"

[[4]]
[1] "d"

[[5]]
[1] "a" "b"

[[6]]
[1] "a" "c"

[[7]]
[1] "a" "d"

[[8]]
[1] "b" "c"

[[9]]
[1] "b" "d"

[[10]]
[1] "c" "d"

[[11]]
[1] "a" "b" "c"

[[12]]
[1] "a" "b" "d"

[[13]]
[1] "a" "c" "d"

[[14]]
[1] "b" "c" "d"

[[15]]
[1] "a" "b" "c" "d"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM