Reputation: 81
Imagine that we have three vectors:
v_1 = c("a", "b", "c", "d")
v_2 = c("e", "f", "g")
v_3 = c("h", "i")
I'd like to use R to retrieve a complete list of all combinations of these three vectors for all possible lengths under the condition that:
v_1
)Given that I have done the math correctly, we should end up with 59 distinct combinations of lengths 1 to 3. I've looked into the combn()
function, but it seems difficult (or impossible?) to apply the the two conditions. Does anyone a have suggestion for how to solve this in R?
Thanks!
Upvotes: 1
Views: 166
Reputation: 34441
I think your general approach is sound but can be simplified by passing a list of your vectors directly to combn()
and using expand.grid()
in its function argument. Then all you need to do is bind the output into a data frame.
v_1 = c("a", " b", "c", "d")
v_2 = c("e", "f", "g")
v_3 = c("h", "i")
library(purrr)
library(dplyr)
my_list <- list(v_1, v_2, v_3)
map(seq_along(my_list), ~combn(my_list, .x, FUN = function(x) list(expand.grid(x, stringsAsFactors = FALSE)))) %>%
map_df(bind_rows)
Var1 Var2 Var3
1 a <NA> <NA>
2 b <NA> <NA>
3 c <NA> <NA>
4 d <NA> <NA>
5 e <NA> <NA>
6 f <NA> <NA>
7 g <NA> <NA>
8 h <NA> <NA>
9 i <NA> <NA>
10 a e <NA>
...
58 c g i
59 d g i
Upvotes: 1
Reputation: 81
I added some more thoughts into this and this seems do the trick.
In the first step, I combined all the names of vectors:
vectors = c("v_1", "v_2", "v_3")
Second, I created a list of all mutually exclusive ways these three vectors could be combined:
list_comb_vectors = do.call("c", lapply(seq_along(vectors), function(i) combn(vectors, i, FUN = list)))
Thirdly, I created a function that goes through all of these combinations, i.e., 1 to length(list_comb_vectors)
. I finally make use of the expand.grid()
function:
go_through_combination <- function(v) {
i = list_comb_vectors[[v]]
list_of_vars = do.call("c", lapply(seq_along(i), function(x) paste0(i[x],"=",i[x])))
list_of_expression = paste(list_of_vars, collapse=",")
eval(parse(text = paste0('expand.grid(', list_of_expression, ')')))
}
mapped <- map_df(1:length(list_comb_vectors), go_through_combination)
Even though this solves the issue, I'm sure there is a more elegant solution to the problem.
Upvotes: 0