Reputation: 13123
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
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
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
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