Search code examples
runiquecombn

Create samples from the output of a combn function in R, with no repeated elements


I am trying to solve this problem with R: out of all possible combinations of letters, I want to randomly select a sample of 13 pairs with the condition that no LETTER is repeated.

I am trying the following:

x<- LETTERS
combi <- combn(x, 2, FUN = NULL, simplify = FALSE) #combines by 2
fulltable <- data.frame(Reduce(rbind, combi)) #Convert list to dataframe of 2 columns

It gives me 323 possible combinations:

...
X.316  V  Y
X.317  V  Z
X.318  W  X
X.319  W  Y
X.320  W  Z
X.321  X  Y
X.322  X  Z
X.323  Y  Z

I want to select a sample -lets call it SET1- of 13 pair of letters (there are 26 letters in total) where no letter is repeated. Then, once these pairs are created, I want to extract another sample with the same condition, but in this case, excluding SET1.

Desired outcome:

X.1  A  E
X.2  C  H
X.3  B  X
X.4  W  Y
X.5  F  K
…..

Until X.13 and no letter repeated either in row or column.

In the second sample extraction,again, a combination of pairs with unique letters, but in this case, previous combinations not allowed (i.e. A E / C H). It should also exclude permutations, such as E A / H C.

Thanks AJS

EDIT--------------------- This solution works for me:

test <- LETTERS
ctest <- combn(test, 2, FUN = NULL, simplify = FALSE)
ctabl <- data.frame(Reduce(rbind,ctest))
ctabl$row <- 1:nrow(ctabl)

for (i in 1:nrow(ctabl)){
  sname <- ctabl%>% sample_n(13)
  ctabl <- ctabl %>% subset(!row %in% sname$row)
  print(sname)
}

Solution

  • A simpler approach to obtain comparable results, hope it helps...

    > x  <- sample(LETTERS, replace = F)
    >  ft <- data.frame(x[1:13],x[14:26])
    >  ft
       x.1.13. x.14.26.
    1        X        D
    2        T        Y
    3        P        N
    4        Z        I
    5        M        E
    6        K        V
    7        B        J
    8        R        O
    9        H        C
    10       S        L
    11       A        W
    12       G        Q
    13       U        F
    
    > # UPDATE based on comment:  
    > # That probably moves the post from primarily being R, to being a math problem 
    >  # It depends if you want a comprehensive ste of solutions or a couple unique solutions
    >  # Couple unique solutions is easier: 
    > x1 <- x[1:13]
    
    x1 <- x[1:13]
    
    x2 <- x[14:26];  df2 <- data.frame(x1,x2); df2
    x3 <- x[c(15:26,14)]; df3 <- data.frame(x1,x3); df3
    x4 <- x[c(16:26,14:15)]; df4 <- data.frame(x1,x4); df4
    x5 <- x[c(17:26,14:16)]; df5 <- data.frame(x1,x5); df5
    # .... and so on till x14
    # Implemented code 
    > x1 <- x[1:13]
    > 
    > x2 <- x[14:26];  df2 <- data.frame(x1,x2); df2
       x1 x2
    1   X  D
    2   T  Y
    3   P  N
    4   Z  I
    5   M  E
    6   K  V
    7   B  J
    8   R  O
    9   H  C
    10  S  L
    11  A  W
    12  G  Q
    13  U  F
    > x3 <- x[c(15:26,14)]; df3 <- data.frame(x1,x3); df3
       x1 x3
    1   X  Y
    2   T  N
    3   P  I
    4   Z  E
    5   M  V
    6   K  J
    7   B  O
    8   R  C
    9   H  L
    10  S  W
    11  A  Q
    12  G  F
    13  U  D
    > x4 <- x[c(16:26,14:15)]; df4 <- data.frame(x1,x4); df4
       x1 x4
    1   X  N
    2   T  I
    3   P  E
    4   Z  V
    5   M  J
    6   K  O
    7   B  C
    8   R  L
    9   H  W
    10  S  Q
    11  A  F
    12  G  D
    13  U  Y
    > x5 <- x[c(17:26,14:16)]; df5 <- data.frame(x1,x5); df5
       x1 x5
    1   X  I
    2   T  E
    3   P  V
    4   Z  J
    5   M  O
    6   K  C
    7   B  L
    8   R  W
    9   H  Q
    10  S  F
    11  A  D
    12  G  Y
    13  U  N
    > # .... and so on till x14
    > 
    > # You may need to write a loop /nested loop to get a comprehensive set
    > # logic is - find N, combinations of 2/26 letters, then find the combinations of 13/length(N) those 
    > # with the condition that no character is repeated in a single vector of any combination in any df.