Lohengrin
Lohengrin

Reputation: 125

List of possible combinations from multiple vectors

I am trying to generate all possible cominations (length 3) for the below data. The trick is - we do not want Variables from the the same Stage together. E.g: select 1 variable from Stage1, one from Stage2 and one from Stage 3 or one from Stage 1, one from Stage 4 and one from Stage 5. I was trying to use 'combn" funciton - but it seems to be not ok, I have started working with the expand.grid but not sure on the next steps

My below code:

Stage1<-paste0("VarStage1_", seq(1:6))
Stage2<-paste0("VarStage2_", seq(1:8))
Stage3<-paste0("VarStage3_", seq(1:3))
Stage4<-paste0("VarStage4_", seq(1:4))
Stage5<-paste0("VarStage5_", seq(1:6))

new<-combn(c(Stage1, Stage2, Stage3, Stage4, Stage5, Stage5), 3)
head(t(new)) # not ok, 3 variables from Stage 1 (VarStage1_1,VarStage1_2,VarStage1_3)

my.combinations<-expand.grid(Stage1, Stage2, Stage3) # I can manually add all combinations here eg.: Stage1, Stage2, Stage5
head(my.combinations)

Upvotes: 3

Views: 89

Answers (2)

zephryl
zephryl

Reputation: 17059

The brute force approach would be to generate all combinations, then subset to those with elements from 3 different stages.

new <- combn(c(Stage1, Stage2, Stage3, Stage4, Stage5), 3)

n_stages <- apply(
  new, 
  2, 
  \(x) length(unique(gsub("_\\d+$", "", x)))
)

new <- new[, n_stages == 3]

head(t(new))
     [,1]          [,2]          [,3]         
[1,] "VarStage1_1" "VarStage2_1" "VarStage3_1"
[2,] "VarStage1_1" "VarStage2_1" "VarStage3_2"
[3,] "VarStage1_1" "VarStage2_1" "VarStage3_3"
[4,] "VarStage1_1" "VarStage2_1" "VarStage4_1"
[5,] "VarStage1_1" "VarStage2_1" "VarStage4_2"
[6,] "VarStage1_1" "VarStage2_1" "VarStage4_3”

Upvotes: 2

Rui Barradas
Rui Barradas

Reputation: 76402

Are you looking for something like this?
Put the vectors in a list, create a combinations index and apply expand.grid to each sublist.

Stage1<-paste0("VarStage1_", seq(1:6))
Stage2<-paste0("VarStage2_", seq(1:8))
Stage3<-paste0("VarStage3_", seq(1:3))
Stage4<-paste0("VarStage4_", seq(1:4))
Stage5<-paste0("VarStage5_", seq(1:6))

vec_list <- list(Stage1, Stage2, Stage3, Stage4, Stage5, Stage5)
inx <- combn(length(vec_list), 3)
result <- apply(inx, 2, \(i) expand.grid(vec_list[i]))
lapply(result, head, n = 6)
#> [[1]]
#>          Var1        Var2        Var3
#> 1 VarStage1_1 VarStage2_1 VarStage3_1
#> 2 VarStage1_2 VarStage2_1 VarStage3_1
#> 3 VarStage1_3 VarStage2_1 VarStage3_1
#> 4 VarStage1_4 VarStage2_1 VarStage3_1
#> 5 VarStage1_5 VarStage2_1 VarStage3_1
#> 6 VarStage1_6 VarStage2_1 VarStage3_1
#> 
#> [[2]]
#>          Var1        Var2        Var3
#> 1 VarStage1_1 VarStage2_1 VarStage4_1
#> 2 VarStage1_2 VarStage2_1 VarStage4_1
#> 3 VarStage1_3 VarStage2_1 VarStage4_1
#> 4 VarStage1_4 VarStage2_1 VarStage4_1
#> 5 VarStage1_5 VarStage2_1 VarStage4_1
#> 6 VarStage1_6 VarStage2_1 VarStage4_1
#> 
#> [[3]]
#>          Var1        Var2        Var3
#> 1 VarStage1_1 VarStage2_1 VarStage5_1
#> 2 VarStage1_2 VarStage2_1 VarStage5_1
#> 3 VarStage1_3 VarStage2_1 VarStage5_1
#> 4 VarStage1_4 VarStage2_1 VarStage5_1
#> 5 VarStage1_5 VarStage2_1 VarStage5_1
#> 6 VarStage1_6 VarStage2_1 VarStage5_1
#> 
#> [[4]]
#>          Var1        Var2        Var3
#> 1 VarStage1_1 VarStage3_1 VarStage4_1
#> 2 VarStage1_2 VarStage3_1 VarStage4_1
#> 3 VarStage1_3 VarStage3_1 VarStage4_1
#> 4 VarStage1_4 VarStage3_1 VarStage4_1
#> 5 VarStage1_5 VarStage3_1 VarStage4_1
#> 6 VarStage1_6 VarStage3_1 VarStage4_1
#> 
#> [[5]]
#>          Var1        Var2        Var3
#> 1 VarStage1_1 VarStage3_1 VarStage5_1
#> 2 VarStage1_2 VarStage3_1 VarStage5_1
#> 3 VarStage1_3 VarStage3_1 VarStage5_1
#> 4 VarStage1_4 VarStage3_1 VarStage5_1
#> 5 VarStage1_5 VarStage3_1 VarStage5_1
#> 6 VarStage1_6 VarStage3_1 VarStage5_1
#> 
#> [[6]]
#>          Var1        Var2        Var3
#> 1 VarStage1_1 VarStage4_1 VarStage5_1
#> 2 VarStage1_2 VarStage4_1 VarStage5_1
#> 3 VarStage1_3 VarStage4_1 VarStage5_1
#> 4 VarStage1_4 VarStage4_1 VarStage5_1
#> 5 VarStage1_5 VarStage4_1 VarStage5_1
#> 6 VarStage1_6 VarStage4_1 VarStage5_1
#> 
#> [[7]]
#>          Var1        Var2        Var3
#> 1 VarStage2_1 VarStage3_1 VarStage4_1
#> 2 VarStage2_2 VarStage3_1 VarStage4_1
#> 3 VarStage2_3 VarStage3_1 VarStage4_1
#> 4 VarStage2_4 VarStage3_1 VarStage4_1
#> 5 VarStage2_5 VarStage3_1 VarStage4_1
#> 6 VarStage2_6 VarStage3_1 VarStage4_1
#> 
#> [[8]]
#>          Var1        Var2        Var3
#> 1 VarStage2_1 VarStage3_1 VarStage5_1
#> 2 VarStage2_2 VarStage3_1 VarStage5_1
#> 3 VarStage2_3 VarStage3_1 VarStage5_1
#> 4 VarStage2_4 VarStage3_1 VarStage5_1
#> 5 VarStage2_5 VarStage3_1 VarStage5_1
#> 6 VarStage2_6 VarStage3_1 VarStage5_1
#> 
#> [[9]]
#>          Var1        Var2        Var3
#> 1 VarStage2_1 VarStage4_1 VarStage5_1
#> 2 VarStage2_2 VarStage4_1 VarStage5_1
#> 3 VarStage2_3 VarStage4_1 VarStage5_1
#> 4 VarStage2_4 VarStage4_1 VarStage5_1
#> 5 VarStage2_5 VarStage4_1 VarStage5_1
#> 6 VarStage2_6 VarStage4_1 VarStage5_1
#> 
#> [[10]]
#>          Var1        Var2        Var3
#> 1 VarStage3_1 VarStage4_1 VarStage5_1
#> 2 VarStage3_2 VarStage4_1 VarStage5_1
#> 3 VarStage3_3 VarStage4_1 VarStage5_1
#> 4 VarStage3_1 VarStage4_2 VarStage5_1
#> 5 VarStage3_2 VarStage4_2 VarStage5_1
#> 6 VarStage3_3 VarStage4_2 VarStage5_1

Created on 2023-02-10 with reprex v2.0.2


Edit

Like Allan Cameron's comment says, to have all results in one data.frame,

result <- do.call(rbind, result)

Upvotes: 5

Related Questions