Home > Mobile >  Transform adjacency lists to binary matrix in R
Transform adjacency lists to binary matrix in R

Time:12-18

Given a list of the locations of 1s in each row, I'm trying to find an efficient way to construct a binary matrix. Here's an example -

Given a binary matrix:

> M <- matrix(rbinom(25,1,0.5),5,5)
> M
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    1    1    1    0
[2,]    0    1    1    1    1
[3,]    1    1    0    1    1
[4,]    1    0    0    1    0
[5,]    0    1    1    0    0

I can transform M into an adjacency list using:

> Mlist <- apply(M==1, 1, which, simplify = FALSE)
> Mlist
[[1]]
[1] 2 3 4

[[2]]
[1] 2 3 4 5

[[3]]
[1] 1 2 4 5

[[4]]
[1] 1 4

[[5]]
[1] 2 3

I'd like to transform Mlist back into M. One possibility is:

M.new <- matrix(0,5,5)
for (row in 1:5){M.new[row,Mlist[[row]]] <- 1}

But, it seems like there should be a more efficient way.

Thanks!

CodePudding user response:

Using the vectorized row/column indexing - replicate the sequence of 'Mlist' by the lengths of the 'Mlist', and cbind with the unlisted 'Mlist' to create a matrix which can be used to assign the subset of elements of 'M.new' to 1

ind <- cbind(rep(seq_along(Mlist), lengths(Mlist)), unlist(Mlist))
M.new[ind] <- 1

-checking

> all.equal(M, M.new)
[1] TRUE

Or another option is sparseMatrix

library(Matrix)
as.matrix(sparseMatrix(i = rep(seq_along(Mlist), lengths(Mlist)),
      j = unlist(Mlist), x = 1))
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    1    1    1
[2,]    0    1    0    1    0
[3,]    1    0    0    1    0
[4,]    0    1    0    1    0
[5,]    1    0    1    1    1

CodePudding user response:

1) Using M and Mlist defined in the Note at the end, sapply over its components replacing a vector of zeros with ones at the needed locations. Transpose at the end.

M2 <- t(sapply(Mlist, replace, x = numeric(length(Mlist)), 1))

all.equal(M, M2)  # check that M2 equals M
## [1] TRUE

2) A variation of the above would be:

do.call("rbind", lapply(Mlist, replace, x = numeric(length(Mlist)), 1))

Note

set.seed(123)
M <- matrix(rbinom(25,1,0.5),5,5)
Mlist <- apply(M==1, 1, which, simplify = FALSE)
  • Related