Mark Miller
Mark Miller

Reputation: 13123

all combinations of n numbers

I would like to generate all unique combinations of n numbers without replacement. For example if n = 4, there are gamma(4+1) combinations shown here:

combos4 <- read.table(text='

        x1  x2  x3  x4
         1   2   3   4
         1   2   4   3
         1   3   2   4
         1   3   4   2
         1   4   2   3
         1   4   3   2

         2   1   3   4
         2   1   4   3
         2   3   1   4
         2   3   4   1
         2   4   1   3
         2   4   3   1

         3   1   2   4
         3   1   4   2
         3   2   1   4
         3   2   4   1
         3   4   1   2
         3   4   2   1

         4   1   2   3
         4   1   3   2
         4   2   1   3
         4   2   3   1
         4   3   1   2
         4   3   2   1

', header = TRUE)

I can obtain these 24 combinations using the following code:

combos <- expand.grid(x1=1:4, x2=1:4, x3=1:4, x4=1:4)

my.combos <- combos[apply(combos,1,function(x) length(unique(x)) == ncol(combos)),]
my.combos

However, I always assumed there was an easier way in base R. Specifically, I always assumed the function combn() could return these combinations. However, if combn() can I now realize I do not know how to do it.

The expand.grid approach seems a little inefficient, especially when n is large.

In searching the internet and StackOverflow I have found several similar questions that use the algorithm tag and the code posted in answers, when provided, is not simple. Sorry if this is a duplicate or if I am missing something obvious.

Upvotes: 1

Views: 222

Answers (3)

Randy Lai
Randy Lai

Reputation: 3184

There is also iterpc package.

> I = iterpc(4, ordered=TRUE)
> getall(I)
      [,1] [,2] [,3] [,4]
 [1,]    1    2    3    4
 [2,]    1    2    4    3
 [3,]    1    3    2    4
 [4,]    1    3    4    2
 [5,]    1    4    2    3
 [6,]    1    4    3    2
 [7,]    2    1    3    4
 [8,]    2    1    4    3
 [9,]    2    3    1    4
[10,]    2    3    4    1
...

You can also do it iteratively

> getnext(I)
[1] 1 2 3 4
> getnext(I)
[1] 1 2 4 3
> getnext(I)
[1] 1 3 2 4
> getnext(I)
[1] 1 3 4 2

Upvotes: 2

jdharrison
jdharrison

Reputation: 30455

The combinat package has a permn function

library(combinat)
permn(1:4)

> permn(1:4)
[[1]]
[1] 1 2 3 4

[[2]]
[1] 1 2 4 3

[[3]]
[1] 1 4 2 3

[[4]]
[1] 4 1 2 3

[[5]]
[1] 4 1 3 2

[[6]]
[1] 1 4 3 2

[[7]]
[1] 1 3 4 2

[[8]]
[1] 1 3 2 4

[[9]]
[1] 3 1 2 4

[[10]]
[1] 3 1 4 2

[[11]]
[1] 3 4 1 2

[[12]]
[1] 4 3 1 2

[[13]]
[1] 4 3 2 1

[[14]]
[1] 3 4 2 1

[[15]]
[1] 3 2 4 1

[[16]]
[1] 3 2 1 4

[[17]]
[1] 2 3 1 4

[[18]]
[1] 2 3 4 1

[[19]]
[1] 2 4 3 1

[[20]]
[1] 4 2 3 1

[[21]]
[1] 4 2 1 3

[[22]]
[1] 2 4 1 3

[[23]]
[1] 2 1 4 3

[[24]]
[1] 2 1 3 4

Upvotes: 3

hrbrmstr
hrbrmstr

Reputation: 78832

gtools has a permutations function that might help:

library(gtools)
permutations(4,4,1:4)
##       [,1] [,2] [,3] [,4]
##  [1,]    1    2    3    4
##  [2,]    1    2    4    3
##  [3,]    1    3    2    4
##  [4,]    1    3    4    2
##  [5,]    1    4    2    3
##  [6,]    1    4    3    2
##  [7,]    2    1    3    4
##  [8,]    2    1    4    3
##  [9,]    2    3    1    4
## [10,]    2    3    4    1
## [11,]    2    4    1    3
## [12,]    2    4    3    1
## [13,]    3    1    2    4
## [14,]    3    1    4    2
## [15,]    3    2    1    4
## [16,]    3    2    4    1
## [17,]    3    4    1    2
## [18,]    3    4    2    1
## [19,]    4    1    2    3
## [20,]    4    1    3    2
## [21,]    4    2    1    3
## [22,]    4    2    3    1
## [23,]    4    3    1    2
## [24,]    4    3    2    1

and runs pretty fast:

   user  system elapsed 
  0.001   0.000   0.000 

Upvotes: 3

Related Questions