Search code examples
rmatrixadjacency-matrix

Modifying matrix values based on another matrix without using a loop or apply function


I have two matrices S and A and I would like to modify values of A based on values of S. Matrix S contains indices of matrix A which I would like to modify. For instance

S <- matrix(c(2,3,3,1,1,2),nrow=3, byrow=TRUE)

   [,1] [,2]
[1,]    2    3
[2,]    3    1
[3,]    1    2

The resulting matrix A would be

     [,1] [,2] [,3]
[1,]    0    1    1
[2,]    1    0    1
[3,]    1    1    0


In other words, In matrix S every row represents a graph vertex. Values in every row (say ith) are indices of vertices which are connected to ith vertex. Matrix A is an adjacency matrix of the graph.

Question: How to solve the problem, i.e. obtain matrix A, without using a for loop or apply/sapply/mapply etc. functions? What is the fastest way to do this?

EDIT: An example

S <- matrix(c(2,3,3,1,1,2,1,2),nrow=4, byrow=TRUE)

    [,1] [,2]
[1,]    2    3
[2,]    3    1
[3,]    1    2
[4,]    1    2

The result should be:

     [,1] [,2] [,3] [,4]
[1,]    0    1    1    1
[2,]    1    0    1    1
[3,]    1    1    0    0
[4,]    1    1    0    0




Solution

  • We can use the 'S' as row/column index to change the values in A

    A <- matrix(0, 4, 4)
    A[cbind(c(row(S)), c(S))] <- 1
    +(A|t(A))
    #     [,1] [,2] [,3] [,4]
    #[1,]    0    1    1    1
    #[2,]    1    0    1    1
    #[3,]    1    1    0    0
    #[4,]    1    1    0    0