Search code examples
rlistcombinations

Combinations of varying number of elements from two vectors


I have two vectors:

group1 <- c("a", "b")
group2 <- c("c", "d", "e")

I want get all combinations of one element from 'group1', with one or two elements from 'group2'.

The desired result is:

"a" "c" # one element from group1, one element from group 2
"b" "c"
"a" "d"
"b" "d"
"a" "e"
"b" "e"
"a" "c" "d" # one element from group1, two elements from group 2
"b" "c" "d"
"a" "c" "e"
"b" "c" "e"
"a" "d" "e"
"b" "d" "e"

Solution

  • A completely general solution that allows for any input vectors and the maximum / minimum numbers of characters taken from each would be:

    comb <- function(a, b, min_a = 1, max_a = 1, min_b = 1, max_b = 2) {
      as <- do.call(c, lapply(min_a:max_a, \(i) combn(a, i, simplify = FALSE)))
      bs <- do.call(c, lapply(min_b:max_b, \(i) combn(b, i, simplify = FALSE)))
      apply(expand.grid(as, bs), 1, unlist, use.names = FALSE)
    }
    

    By default this would give:

    comb(group1, group2)
    #> [[1]]
    #> [1] "a" "c"
    #> 
    #> [[2]]
    #> [1] "b" "c"
    #> 
    #> [[3]]
    #> [1] "a" "d"
    #> 
    #> [[4]]
    #> [1] "b" "d"
    #> 
    #> [[5]]
    #> [1] "a" "e"
    #> 
    #> [[6]]
    #> [1] "b" "e"
    #> 
    #> [[7]]
    #> [1] "a" "c" "d"
    #> 
    #> [[8]]
    #> [1] "b" "c" "d"
    #> 
    #> [[9]]
    #> [1] "a" "c" "e"
    #> 
    #> [[10]]
    #> [1] "b" "c" "e"
    #> 
    #> [[11]]
    #> [1] "a" "d" "e"
    #> 
    #> [[12]]
    #> [1] "b" "d" "e"
    

    Created on 2022-09-03 with reprex v2.0.2