2014-11-20 1 views
2

다음 목록이 있습니다.목록에서 R의 모든 조합을 가져 오는 동쪽 방법

그룹 1에서 1 개, 그룹 2에서 2 개, 그룹 3에서 3 개, 그룹 4 - 6에서 1 개를 원한다고 가정하십시오. 요소 반복이 허용되지 않는 경우 모든 다른 요소 조합을 얻는 가장 유사한 방법은 무엇입니까?

예 : (A1, B1, B2, C1, C2, C3, D1, E1, F1)은 괜찮지 만 (A1, B1, B1, C1, C2, C3, D1, E1, F1)은 맞지 않습니까?

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

분명히, 나는 9 중첩 루프 - 낭비로 이것을 할 수있다. 나는 녹아서 재연했지만 2 아무데도 못 받았다. 감사!

+0

어떤 항목이 둘 이상의 그룹에 속할 수 있습니까? – blakeoft

+0

@blakeoft - 아니요. "가치"가 있다고하더라도, 그것은 여전히 ​​별도의 실체로 간주되어야합니다. – user1357015

+0

확인. 그룹 6은 어때? 나는 그것이 단지 하나의 끌기를 가져야 만한다고 가정하고 있습니다. – blakeoft

답변

3

당신은 MapReduce 기능을 조합하여 사용할 수 있습니다. 각 그룹의 조합을 얻으려면 combn을 매핑하십시오. 그런 다음 평평하지 않은 expand.grid 버전으로 줄입니다.

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 
2
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" 

없음 중복 :

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

또 다른 반복

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 
관련 문제