I have a matrix indicating in which column there should be a value 1. All other columns should have a value of 0. For example,
m = matrix(c(3,3,3,5,12,13),nrow = 3)
How should I efficitietly create the following matrix?
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
[,1] 0 0 1 0 1 0 0 0 0 0 0 0 0 0
[,2] 0 0 1 0 0 0 0 0 0 0 0 1 0 0
[,3] 0 0 1 0 0 0 0 0 0 0 0 0 1 0
Thank you
CodePudding user response:
You can create a matrix of 0's with desired dimensions
out <- matrix(0, nrow = 3, ncol = 14)
Then cbind
a vector of row indices with c(m)
, i.e. column positions
tmp <- cbind(seq_len(3), c(m))
tmp
is a matrix that you can use now to replace desired positions with 1
out[tmp] <- 1
out
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
# [1,] 0 0 1 0 1 0 0 0 0 0 0 0 0 0
# [2,] 0 0 1 0 0 0 0 0 0 0 0 1 0 0
# [3,] 0 0 1 0 0 0 0 0 0 0 0 0 1 0
Another, probably less efficient way, could be this
t(apply(m, 1, tabulate, nbins = 14))
CodePudding user response:
Create a matrix of row ids and elements from your original matrix m1
Create a matrix poplulated with zeros with the same number of rows as the original and number of columns one more than the maximium element in the original.
m1 <- matrix(c(rep(1:nrow(m), ncol(m)), as.vector(m)), ncol = 2)
mx <- matrix(0, nrow = 3, ncol = max(m) 1)
mx[m1] <- 1
mx
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
#> [1,] 0 0 1 0 1 0 0 0 0 0 0 0 0 0
#> [2,] 0 0 1 0 0 0 0 0 0 0 0 1 0 0
#> [3,] 0 0 1 0 0 0 0 0 0 0 0 0 1 0
Created on 2022-03-23 by the reprex package (v2.0.1)