domaeg domaeg - 26 days ago 8
R Question

Fast way to create a binary indicator matrix in R

I have a vector that provides how many "1" each row of a matrix has. Now I have to create this matrix out of the vector.
E.g let say I want to create a 4 x 9 matrix

out
with following vector
v <- c(2,6,3,9)
. The result should look like this

out
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 1 1 0 0 0 0 0 0 0
[2,] 1 1 1 1 1 1 0 0 0
[3,] 1 1 1 0 0 0 0 0 0
[4,] 1 1 1 1 1 1 1 1 1


I've done this with a for loop but my solution is slow for a large matrix (100k x 500):

out <- NULL
for(i in 1:length(v)){
out <- rbind(out,c(rep(1, v[i]),rep(0,9-v[i])))
}


Has anyone an idea for a faster way to create such a matrix?
Thanks!

42- 42-
Answer

vapply is usually faster than sapply. This assigns the desired number of ones to a length-9 vector and then transposes.

> t( vapply( c(2,6,3,9), function(y) { x <- numeric( length=9); x[1:y] <- 1;x}, numeric(9) ) )
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,]    1    1    0    0    0    0    0    0    0
[2,]    1    1    1    1    1    1    0    0    0
[3,]    1    1    1    0    0    0    0    0    0
[4,]    1    1    1    1    1    1    1    1    1

Less than 5 seconds on an old Mac.

 system.time( M <- t( vapply( sample(1:500, 100000, rep=TRUE), function(y) { x <- numeric( length=500); x[1:y] <- 1;x}, numeric(500) ) ) )
   user  system elapsed 
  3.531   1.208   4.676 
Comments