Scott Gigante
Scott Gigante

Reputation: 1635

Generate all possible binary vectors of length n in R

I'm looking to generate all possible binary vectors of length n in R. What is the best way (preferably both computationally efficient and readable code) to do this?

Upvotes: 3

Views: 4109

Answers (3)

d.b
d.b

Reputation: 32548

n = 3
expand.grid(replicate(n, 0:1, simplify = FALSE))
#  Var1 Var2 Var3
#1    0    0    0
#2    1    0    0
#3    0    1    0
#4    1    1    0
#5    0    0    1
#6    1    0    1
#7    0    1    1
#8    1    1    1

Upvotes: 10

djhurio
djhurio

Reputation: 5536

You should define what is "the best way" (fastest? shortest code?, etc.).

One way is to use the package R.utils and the function intToBin for converting decimal numbers to binary numbers. See the example.

require(R.utils)
n <- 5
strsplit(intToBin(0:(2 ^ n - 1)), split = "")

Upvotes: 0

Scott Gigante
Scott Gigante

Reputation: 1635

Inspired by this question generating all possible binary vectors of length n containing less than m 1s, I've extended this code to produce all possible combinations. It's not pretty, though.

> z <- 3
> z <- rep(0, n)
> do.call(rbind, lapply(0:n, function(i) t(apply(combn(1:n,i), 2, function(k) {z[k]=1;z}))))
     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    1    0    0
[3,]    0    1    0
[4,]    0    0    1
[5,]    1    1    0
[6,]    1    0    1
[7,]    0    1    1
[8,]    1    1    1

What is it doing? Once we strip it back, the core of this one-liner is the following:

apply(combn(1:n,i), 2, function(k) {z[k]=1;z})

To understand this, let's step back one level further. The function combn(x,m) generates all possible combinations of x taken m at a time.

> combn(1:n, 1)
     [,1] [,2] [,3]
[1,]    1    2    3
> combn(1:n, 2)
     [,1] [,2] [,3]
[1,]    1    1    2
[2,]    2    3    3
> combn(1:n, 3)
     [,1]
[1,]    1
[2,]    2
[3,]    3

For using apply(MARGIN=2), we pass in a column of this function at a time to our inner function function(k) {z[k]=1;z} which simply replaces all of the values at the indices k with 1. Since they were originally all 0, this gives us each possible binary vector.

The rest is just window dressing. combn gives us a wide, short matrix; we transpose it with t. lapply returns a list; we bind the matrices in each element of the list together with do.call(rbind, .).

Upvotes: 0

Related Questions