# 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!
> 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
... Perhaps worth noting is that the row indices can be created directly without row(): result[cbind(rep.int(seq_len(6),5), as.vector(x))] <- 1 but the downside is that you have to know that a matrix is a vector "stored" in column major order. I find this arcane detail quite handy, though. Cheers, Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Tue, Dec 22, 2015 at 3:03 PM, Marc Schwartz <marc_schwartz at me.com> wrote:> >> 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 > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.