Search code examples
rmatrixadjacency-matrix

Making adjacency matrix from matrix indicating relations


I have created a matrix S, which describes a graph. It looks like this:

   [,1] [,2] [,3]
1     2    3    9
2     1   10    5
3     9    4    8
4     3    9    7
5    10    4   11
6    11    5   10
7     4    3    8
8     9    3    4
9     3    8    4
10    5    2   11
11    6    5   10

It means that 3rd vertex is connected with 9th, 4th and 8th vertex. My graph is not directed. I would like to create an adjacency matrix. For example the third row would be:

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

I thought about creating a matrix 11x11 of zeros and analise it row by row. My result matrix should be symmetirc. However I cannot use any loops, "for" is forbidden. I am mathematician and i'm totally new to R. How should I start solving this problem?

Data

S <- structure(c(2L, 1L, 9L, 3L, 10L, 11L, 4L, 9L, 3L, 5L, 6L, 3L, 
10L, 4L, 9L, 4L, 5L, 3L, 3L, 8L, 2L, 5L, 9L, 5L, 8L, 7L, 11L,
10L, 8L, 4L, 4L, 11L, 10L), .Dim = c(11L, 3L))

Solution

  • I think you can try the following base R code

    v <- rep(0,nrow(S))
    C <- t(apply(S,1,function(k) replace(v,k,1)))
    res <- +(t(C) + C >0)
    

    which gives the adjacency matrix as

          [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
     [1,]    0    1    1    0    0    0    0    0    1     0     0
     [2,]    1    0    0    0    1    0    0    0    0     1     0
     [3,]    1    0    0    1    0    0    1    1    1     0     0
     [4,]    0    0    1    0    1    0    1    1    1     0     0
     [5,]    0    1    0    1    0    1    0    0    0     1     1
     [6,]    0    0    0    0    1    0    0    0    0     1     1
     [7,]    0    0    1    1    0    0    0    1    0     0     0
     [8,]    0    0    1    1    0    0    1    0    1     0     0
     [9,]    1    0    1    1    0    0    0    1    0     0     0
    [10,]    0    1    0    0    1    1    0    0    0     0     1
    [11,]    0    0    0    0    1    1    0    0    0     1     0
    

    If you would like to use igraph, here is another option

    library(igraph)
    df <- data.frame(from = rep(1:nrow(S), each = ncol(S)), to = c(t(S)))
    res <- as_adjacency_matrix(
      simplify(
        graph_from_data_frame(
          df,
          directed = FALSE
        )
      ),
      sparse = FALSE
    )
    

    which gives

       1 2 3 4 5 6 7 8 9 10 11
    1  0 1 1 0 0 0 0 0 1  0  0
    2  1 0 0 0 1 0 0 0 0  1  0
    3  1 0 0 1 0 0 1 1 1  0  0
    4  0 0 1 0 1 0 1 1 1  0  0
    5  0 1 0 1 0 1 0 0 0  1  1
    6  0 0 0 0 1 0 0 0 0  1  1
    7  0 0 1 1 0 0 0 1 0  0  0
    8  0 0 1 1 0 0 1 0 1  0  0
    9  1 0 1 1 0 0 0 1 0  0  0
    10 0 1 0 0 1 1 0 0 0  0  1
    11 0 0 0 0 1 1 0 0 0  1  0