Eastern way to get all combinations from R from the list

I have a list below.

Suppose I want 1 element from group 1, 2 from group 2, 3 from group 3, 1 from groups 4 to 6. What is the most R-way to get all the different combinations of elements if the elements cannot be repeated.

So, for example: (A1, B1, B2, C1, C2, C3, D1, E1, F1) normal, but (A1, B1, B1, C1, C2, C3, D1, E1, F1) not?

 itemNames <- list(group1 = c("A1", "A2", "A3", "A4", "A5", "A6"), group2 = c("B1", "B2", "B3", "B4", "B5", "B6"), group3 = c("C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10", "C11", "C12"), group4 = c("D1", "D2", "D3", "D4", "D5", "D6"), group5 = c("E1", "E2", "E3", "E4"), group6 = c("F1", "F2", "F3", "F4")) 

Obviously, I can do this with 9 nested loops - waste. I played with melt and change2, but received nothing. Thanks!

+2
source share
3 answers

You can use the functional combination of Map Reduce . combn for getting combinations of each group. Then expand.grid with the expand.grid version, which will not smooth out.

 expand.grid.XY <- function(X,Y) cbind(X[rep(1:nrow(X),nrow(Y)),], Y[rep(1:nrow(Y),each=nrow(X)),]) combos <- function(items,reps) Reduce(expand.grid.XY, Map(function(...) t(combn(...)),items,reps)) dim(combos(itemNames,c(1,2,3,1,1,1))) # [1] 1900800 9 
+3
source
 itemNames <- list(group1 = c("A1","A2","A3","A4","A5","A6"), group2 = c("B1","B2","B3","B4","B5","B6"), group3 = c("C1","C2","C3","C4","C5","C6","C7","C8","C9","C10","C11","C12"), group4 = c("D1","D2","D3","D4","D5","D6"), group5 = c("E1","E2","E3","E4"), group6 = c("F1","F2","F3","F4")) f <- function(x, n) { tmp <- t(combn(length(x),n)) p <- function(...) paste(..., sep = ',') do.call('p', lapply(1:n, function(xx) as.matrix(x)[tmp[, xx]])) } tmp <- Map(f, itemNames, c(1,2,3,1,1,1)) Reduce(`*`, Map(choose, sapply(tmp, length), 1)) # [1] 1900800 dim(out <- expand.grid(tmp)) # [1] 1900800 6 format(object.size(out), units = 'Mb') # [1] "43.5 Mb" head(out) # group1 group2 group3 group4 group5 group6 # 1 A1 B1B2 C1C2C3 D1 E1 F1 # 2 A2 B1B2 C1C2C3 D1 E1 F1 # 3 A3 B1B2 C1C2C3 D1 E1 F1 # 4 A4 B1B2 C1C2C3 D1 E1 F1 # 5 A5 B1B2 C1C2C3 D1 E1 F1 # 6 A6 B1B2 C1C2C3 D1 E1 F1 out <- apply(out, 1, paste0, collapse = ',') (out <- strsplit(out, ','))[1:5] # [[1]] # [1] "A1" "B1" "B2" "C1" "C2" "C3" "D1" "E1" "F1" # # [[2]] # [1] "A2" "B1" "B2" "C1" "C2" "C3" "D1" "E1" "F1" # # [[3]] # [1] "A3" "B1" "B2" "C1" "C2" "C3" "D1" "E1" "F1" # # [[4]] # [1] "A4" "B1" "B2" "C1" "C2" "C3" "D1" "E1" "F1" # # [[5]] # [1] "A5" "B1" "B2" "C1" "C2" "C3" "D1" "E1" "F1" 

No duplicates:

 any(duplicated(out)) # [1] FALSE 
+2
source

Another iteration

 ex <- c(1,2,3,1,1,1) lst <- lapply(seq(itemNames), function(i) combn(itemNames[[i]], ex[i], toString)) out <- do.call("expand.grid", lst) head(out) # Var1 Var2 Var3 Var4 Var5 Var6 #1 A1 B1, B2 C1, C2, C3 D1 E1 F1 #2 A2 B1, B2 C1, C2, C3 D1 E1 F1 #3 A3 B1, B2 C1, C2, C3 D1 E1 F1 #4 A4 B1, B2 C1, C2, C3 D1 E1 F1 #5 A5 B1, B2 C1, C2, C3 D1 E1 F1 #6 A6 B1, B2 C1, C2, C3 D1 E1 F1 dim(out) #[1] 1900800 6 prod(sapply(lst, length)) #[1] 1900800 
+2
source

Source: https://habr.com/ru/post/1212733/


All Articles