Non-redundant version of expand.grid

后端 未结 7 1277
北海茫月
北海茫月 2020-12-01 01:56

The R function expand.grid returns all possible combination between the elements of supplied parameters. e.g.

> expand.grid(c(\"         


        
相关标签:
7条回答
  • 2020-12-01 02:49

    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:

    • When the order doesn't matter, it is a Combination.
    • When the order does matter it is a Permutation.

    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.

    Permutations with repetition

    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).

    Combinations with repetitions

    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.

    Permutations without repetition

    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.

    Combinations without repetitions

    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.

    0 讨论(0)
提交回复
热议问题