The R
function expand.grid
returns all possible combination between the elements of supplied parameters. e.g.
> expand.grid(c(\"
The previous answers were lacking a way to get a specific result, namely to keep the self-pairs but remove the ones with different orders. The gtools package has two functions for these purposes, combinations
and permutations
. According to this website:
In both cases, we have the decision to make of whether repetitions are allowed or not, and correspondingly, both functions have a repeats.allowed
argument, yielding 4 combinations (deliciously meta!). It's worth going over each of these. I simplified the vector to single letters for ease of understanding.
The most expansive option is to allow both self-relations and differently ordered options:
> permutations(n = 3, r = 2, repeats.allowed = T, v = c("a", "b", "c"))
[,1] [,2]
[1,] "a" "a"
[2,] "a" "b"
[3,] "a" "c"
[4,] "b" "a"
[5,] "b" "b"
[6,] "b" "c"
[7,] "c" "a"
[8,] "c" "b"
[9,] "c" "c"
which gives us 9 options. This value can be found from the simple formula n^r
i.e. 3^2=9
. This is the Cartesian product/join for users familiar with SQL.
There are two ways to limit this: 1) remove self-relations (disallow repetitions), or 2) remove differently ordered options (i.e. combinations).
If we want to remove differently ordered options, we use:
> combinations(n = 3, r = 2, repeats.allowed = T, v = c("a", "b", "c"))
[,1] [,2]
[1,] "a" "a"
[2,] "a" "b"
[3,] "a" "c"
[4,] "b" "b"
[5,] "b" "c"
[6,] "c" "c"
which gives us 6 options. The formula for this value is (r+n-1)!/(r!*(n-1)!)
i.e. (2+3-1)!/(2!*(3-1)!)=4!/(2*2!)=24/4=6
.
If instead we want to disallow repetitions, we use:
> permutations(n = 3, r = 2, repeats.allowed = F, v = c("a", "b", "c"))
[,1] [,2]
[1,] "a" "b"
[2,] "a" "c"
[3,] "b" "a"
[4,] "b" "c"
[5,] "c" "a"
[6,] "c" "b"
which also gives us 6 options, but different ones! The number of options is the same as above but it's a coincidence. The value can be found from the formula n!/(n-r)!
i.e. (3*2*1)/(3-2)!=6/1!=6
.
The most limiting is when we want neither self-relations/repetitions or differently ordered options, in which case we use:
> combinations(n = 3, r = 2, repeats.allowed = F, v = c("a", "b", "c"))
[,1] [,2]
[1,] "a" "b"
[2,] "a" "c"
[3,] "b" "c"
which gives us only 3 options. The number of options can be calculated from the rather complex formula n!/(r!(n-r)!)
i.e. 3*2*1/(2*1*(3-2)!)=6/(2*1!)=6/2=3
.