1

Is there a way in R to create binary sets of m, filled with all combinations of n by columns, while by row only 1 value can be "1"?

For example, for n=2 and m=2, we would have the following combinations of m each:

(00, 00), (10,00), (01,00), (00,10), (00,01), (10,01), (01,10), (10,10), (01,01)

But these, for example, are not allowed: (11,00), (01,11), (00,11), (11,10), (11,11)

user971102
  • 3,005
  • 4
  • 30
  • 37

1 Answers1

2

This is very similar to your other question. In my answer to that question, we see that rephrasing the question, makes it much easier to attack. So for this question, we can reduce it to: "How to generate all pairwise permutations of powers of 2 with repeats?"

We can use almost exactly the same setup as before, only this time we set the argument repeats.allowed = TRUE.

library(gtools)
bitPairwise2 <- function(numBits, groupSize) {
  t(sapply(t(permutations(numBits + 1, groupSize, 
                           c(0, 2^(0:(numBits-1))), repeats.allowed = TRUE)), 
           function(x) {as.integer(intToBits(x))})[1:numBits, ])
}

bitPairwise2(2,2)
      [,1] [,2]
 [1,]    0    0    ## (00,00)
 [2,]    0    0

 [3,]    0    0    ## (00,10)
 [4,]    1    0

 [5,]    0    0    ## (00,01)
 [6,]    0    1

 [7,]    1    0    ## (10,00)
 [8,]    0    0

 [9,]    1    0    ## (10,10)
[10,]    1    0

[11,]    1    0    ## (10,01)
[12,]    0    1

This function generalizes to any number of bits as well as any number of groups. For example, all possible 3-tuples of 3 bits is given by:

## first 9 groups
bitPairwise2(3, 3)[1:27, ]
      [,1] [,2] [,3]
 [1,]    0    0    0    ## (000,000,000)
 [2,]    0    0    0
 [3,]    0    0    0

 [4,]    0    0    0    ## (000,000,100)
 [5,]    0    0    0
 [6,]    1    0    0

 [7,]    0    0    0    ## (000,000,010)
 [8,]    0    0    0
 [9,]    0    1    0

[10,]    0    0    0    ## (000,000,001)
[11,]    0    0    0
[12,]    0    0    1

[13,]    0    0    0    ## (000,100,000)
[14,]    1    0    0
[15,]    0    0    0

[16,]    0    0    0    ## (000,100,100)
[17,]    1    0    0
[18,]    1    0    0

[19,]    0    0    0    ## (000,100,010)
[20,]    1    0    0
[21,]    0    1    0

[22,]    0    0    0    ## (000,100,001)
[23,]    1    0    0
[24,]    0    0    1

[25,]    0    0    0    ## (000,010,000)
[26,]    0    1    0
[27,]    0    0    0

And here are the last 9 groups:

a <- bitPairwise2(3, 3)[166:192, ]
row.names(a) <- 166:192
a
    [,1] [,2] [,3]
166    0    0    1    ## (001,100,001)
167    1    0    0
168    0    0    1

169    0    0    1    ## (001,010,000)
170    0    1    0
171    0    0    0

172    0    0    1    ## (001,010,100)
173    0    1    0
174    1    0    0

175    0    0    1    ## (001,010,010)
176    0    1    0
177    0    1    0

178    0    0    1    ## (001,010,001)
179    0    1    0
180    0    0    1

181    0    0    1    ## (001,001,000)
182    0    0    1
183    0    0    0

184    0    0    1    ## (001,001,100)
185    0    0    1
186    1    0    0

187    0    0    1    ## (001,001,010)
188    0    0    1
189    0    1    0

190    0    0    1    ## (001,001,001)
191    0    0    1
192    0    0    1

If you need the output in a list, try this:

test <- bitPairwise2(4, 3)
numGroups <- nrow(test)/3

makeGroupList <- function(mat, nG, groupSize) {
    lapply(1:nG, function(x) {
        s <- groupSize*(x-1) + 1
        e <- s + (groupSize - 1)
        mat[s:e, ]
    })
}

makeGroupList(test, numGroups, 3)
[[1]]
     [,1] [,2] [,3] [,4]
[1,]    0    0    0    0
[2,]    0    0    0    0
[3,]    0    0    0    0

[[2]]
     [,1] [,2] [,3] [,4]
[1,]    0    0    0    0
[2,]    0    0    0    0
[3,]    1    0    0    0

[[3]]
     [,1] [,2] [,3] [,4]
[1,]    0    0    0    0
[2,]    0    0    0    0
[3,]    0    1    0    0

 .      .    .    .    .
 .      .    .    .    .
 .      .    .    .    .
Joseph Wood
  • 7,077
  • 2
  • 30
  • 65
  • 1
    I am in awe. Thank you so much Joseph, and for your amazing explanation. – user971102 Jan 18 '18 at 19:03
  • Just one last question, I get an error when using e.g. bitPairwise2(109, 3) - Error in sapply(t(permutations(numBits + 1, groupSize, c(0, 2^(0:(numBits - subscript out of bounds, is this because of R limits? Can it not work when the combinations are this great? Thanks again. – user971102 Jan 19 '18 at 23:57
  • 1
    @user971102 After you get the error, you should also get the message `In addition: There were 50 or more warnings (use warnings() to see the first 50)`. If you type `warnings()`, you will see `In intToBits(x) : NAs introduced by coercion to integer range`. This happens because the vector `c(0, 2^(0:(numBits - 1))` with `numBits = 109` will have a maximal element of `2^108 = 3.245186e+32`. This is way to big for `intToBit` to work on (it only accepts integers (max = `2^31 - 1`)). You will need a different approach to work on problems of this size. – Joseph Wood Jan 20 '18 at 00:16
  • Got it! Thank you!! – user971102 Jan 20 '18 at 00:17