1
votes

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))
2

2 Answers

1
votes

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
1
votes

Here is an option with row/column assignment

m1 <- matrix(0, nrow = nrow(S), ncol = max(S))
m1[cbind(rep(seq_len(nrow(S)), each = ncol(S)), c(t(S)))] <- 1
+(m1|t(m1))

-output

#       [,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

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))