domaeg - 1 year ago 60

R Question

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`

`v <- c(2,6,3,9)`

`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!

Answer Source

`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
```