5

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.

Joseph Wood
  • 7,077
  • 2
  • 30
  • 65
Jian
  • 365
  • 1
  • 6
  • 19
  • what do you mean a combination of `a,a,a` what kind of combination is that? – Onyambu Mar 29 '18 at 19:32
  • I mean possibilities combining the elements in the vector source. – Jian Mar 29 '18 at 19:36
  • So how do you call it a unique combination while you are not ccombining it to anything? but rather repeating it? – Onyambu Mar 29 '18 at 19:38
  • The uniqueness is to say, for instance, aab, aba, baa are the same. – Jian Mar 29 '18 at 19:54
  • I think you are after the [multichoose combinations](http://mathworld.wolfram.com/Multichoose.html). It looks like the [`itertools`](https://cran.r-project.org/web/packages/iterpc/iterpc.pdf) can help you with it's `np_` or `nc_` `multiset` functions – Gregor Thomas Mar 29 '18 at 20:05

3 Answers3

7

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.

Joseph Wood
  • 7,077
  • 2
  • 30
  • 65
1
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" 
Onyambu
  • 67,392
  • 3
  • 24
  • 53
0

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"

jamesjin63
  • 21
  • 2
  • 6
    Welcome to Stack Overflow! While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Yunnosch Apr 19 '22 at 06:02
  • 3
    https://stackoverflow.com/editing-help – Yunnosch Apr 19 '22 at 06:02