Create matrix of 1s from array of counts

84 Views Asked by At

Given an array of length 6 of 3 unique numbers, say:

c(1,1,1,2,3,3)

How can I construct the following 6x3 matrix:

[1, 0 , 0]  
[1, 0 , 0]  
[1, 0 , 0]  
[0, 1 , 0]  
[0, 0, 1]  
[0, 0, 1]

A naive way would be:

V = c(1,1,1,2,3,3)
Z = matrix(0,6,3)
for (i in 1:6) {Z[i, V[i]] = 1}

but is there a nice one liner for this type of operation?

4

There are 4 best solutions below

0
On BEST ANSWER

We may use model.matrix in base R

model.matrix(~ . - 1, data.frame(v1 = factor(v1)))

-output

   v11 v12 v13
1   1   0   0
2   1   0   0
3   1   0   0
4   0   1   0
5   0   0   1
6   0   0   1

Or use dummy_cols from fastDummies

library(fastDummies)
dummy_cols(v1)[-1]
  .data_1 .data_2 .data_3
1       1       0       0
2       1       0       0
3       1       0       0
4       0       1       0
5       0       0       1
6       0       0       1

data

v1 <- c(1,1,1,2,3,3)
0
On

We could vapply a tablulate

t(vapply(v1, \(x) tabulate(x, max(v1)), numeric(max(v1))))
#      [,1] [,2] [,3]
# [1,]    1    0    0
# [2,]    1    0    0
# [3,]    1    0    0
# [4,]    0    1    0
# [5,]    0    0    1
# [6,]    0    0    1

Data:

v1 <- c(1, 1, 1, 2, 3, 3)
0
On

with the modelr:

library(modelr)
V = c(1,1,1,2,3,3)
V <- factor(V)
Z <- as.matrix(model_matrix(V , ~ V -1))
Z
    V1 V2 V3
[1,]  1  0  0
[2,]  1  0  0
[3,]  1  0  0
[4,]  0  1  0
[5,]  0  0  1
[6,]  0  0  1
0
On

Try outer:

V = c(1,1,1,2,3,3)
+outer(V, unique(V), `==`)
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    1    0    0
## [3,]    1    0    0
## [4,]    0    1    0
## [5,]    0    0    1
## [6,]    0    0    1