# [R] Expanding matrix into dummies

Marc Schwartz marc_schwartz at me.com
Wed Dec 23 00:03:05 CET 2015

> On Dec 22, 2015, at 4:42 PM, Dimitri Liakhovitski <dimitri.liakhovitski at gmail.com> wrote:
>
> # I have a matrix x:
>
> k <- 20
> N <- 5
> set.seed(123)
> x <- matrix(c(sample(1:k, N, replace = F),
>              sample(1:k, N, replace = F),
>              sample(1:k, N, replace = F),
>              sample(1:k, N, replace = F),
>              sample(1:k, N, replace = F),
>              sample(1:k, N, replace = F)), byrow = T, ncol = 5)
> colnames(x) <- paste0("column", 1:5)
> (x)
>
> # I want to reshape it into a matrix 'result' with k columns (not N).
> # 'result' should contain the same number of rows as x, and it should have
> # in each row 1s in those columns that correspond to the entries in x
> in the same row.
> # For example, the first row of 'result' should contain 1s in columns
> 6, 8, 15, 16, and 17, etc.
> # The remaining entries should be zeros.
>
> result <- matrix(rep(0, nrow(x) * k), nrow = nrow(x))
> colnames(result) <- paste0("item", 1:k)
>
> # I can see how to do it by looping through rows of result.
> # But I need to do it fast (not using a loop).
> # I feel like I should subset 'result' with 'x', but I am not sure how.
>
> Thank you very much!

Something like this might work for you:

result <- matrix(0, nrow(x), k)

> result
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    0    0    0    0    0    0    0    0    0     0     0     0
[2,]    0    0    0    0    0    0    0    0    0     0     0     0
[3,]    0    0    0    0    0    0    0    0    0     0     0     0
[4,]    0    0    0    0    0    0    0    0    0     0     0     0
[5,]    0    0    0    0    0    0    0    0    0     0     0     0
[6,]    0    0    0    0    0    0    0    0    0     0     0     0
[,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
[1,]     0     0     0     0     0     0     0     0
[2,]     0     0     0     0     0     0     0     0
[3,]     0     0     0     0     0     0     0     0
[4,]     0     0     0     0     0     0     0     0
[5,]     0     0     0     0     0     0     0     0
[6,]     0     0     0     0     0     0     0     0

result[cbind(as.vector(row(x)), as.vector(x))] <- 1

> result
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    0    0    0    0    0    1    0    1    0     0     0     0
[2,]    1    0    0    0    0    0    0    1    0     1     1     0
[3,]    0    1    0    0    0    0    0    0    1     1     0     0
[4,]    1    0    0    0    1    1    0    0    0     0     0     0
[5,]    0    0    0    0    0    0    0    0    0     0     1     1
[6,]    0    0    1    0    1    0    0    0    0     0     1     0
[,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
[1,]     0     0     1     1     1     0     0     0
[2,]     0     0     0     0     1     0     0     0
[3,]     1     0     0     0     0     0     0     1
[4,]     0     0     0     1     0     1     0     0
[5,]     0     1     0     0     1     1     0     0
[6,]     0     0     1     0     0     0     1     0

See ?row

Regards,

Marc Schwartz