0
votes

I have a graph with some parallel edges as exemplified by the adjacency matrix below:

> as_adjacency_matrix(g)
45 x 45 sparse Matrix of class "dgCMatrix"
   [[ suppressing 45 column names ‘1’, ‘2’, ‘3’ ... ]]
   [[ suppressing 45 column names ‘1’, ‘2’, ‘3’ ... ]]

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

I need to add attributes to the edges. Fortunately, the parallel edges between the nodes will have identical attributes. The attributes to add are in a matrix of the same dimension as the adjacency matrix:

> edge_attr_mat
           1        2        3          4        5        6         7        8        9        10       11       12
1       0.00      0.0      0.0  68299.332      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
2       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
3       0.00      0.0      0.0 102016.916      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
4   68299.33      0.0 102016.9      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
5       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
6       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
7       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
8       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
9       0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
10      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
11      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
12      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
13      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
14      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
15      0.00      0.0      0.0 380794.817 154931.3     0.00     0.000    0.000     0.00     0.000     0.00     0.00
16      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
17      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
18      0.00      0.0      0.0      0.000      0.0     0.00     0.000    0.000     0.00     0.000     0.00     0.00
....

I tried using this matrix as a weighted adjacency matrix to re-create the network such that the edge attributes are now present:

g<-graph_from_adjacency_matrix(edge_attr_mat, mode=c("undirected"), diag = F, weighted = T)

However, I am losing the parallel edges as they are being collapsed to a single edge between nodes.

Is there a way to add the attributes to the edges (and parallel edges) using a function or matrix based operation without looping through each entry?

UPDATE

Small representative dataset to help with answering:

g <- make_empty_graph(n = 4) %>%
+     add_edges(c(1,2, 2,4, 3,4, 1,3, 1,4)) %>%
+     set_edge_attr("type", value = "friend") %>%
+     add_edges(c(1,3, 2,4), type = "col")
g <- as.undirected(g, mode = "each")
V(g)$name <-c ("A", "B", "C", "D")
edge_attr_mat<-matrix(data=c(0,1.1,2.12,1.2,1.1,0,0,2.3,2.12,0,0,1.6,1.2,2.3,1.6,0), nrow = 4) #This is the new edge attribute to be added

In the above example, the type edge attribute distinguishes between 2 parallel edges. The new edge attributes is a measure of similarity between two nodes and thus should be the same for all parallel edges between two nodes.

1
I think the problem stems from the fact you are creating an undirected graph. An undirected edge is "parallel" by convention as you can traverse the edge in both directions. In fact if you adj matrix is not symmetrical then you should probably treat it as directed.emilliman5
@emilliman5: Good point. The matrix is symmetrical. Thus, even if I do that, the edges get collapsed into a single edges. Moreover, the edges in my network only make sense as undirected edges.DotPi
If your matrix is symmetrical then you do not need to I do not think you need to "see" two edges in the graph, as they are implicit as undirected edges.emilliman5
@emilliman5: I need to see the multiple edges because they represent two types of connections between two nodes. I need to attach the same additional edge attributes to these parallel edges.DotPi
Please generate a small representative data set so that we can better understand your problem. I am having a hard time understanding why you need to show parallel edges if the attributes for these parallel edges are identical.emilliman5

1 Answers

1
votes

So %u% doesn't seem to work because it combines only the first matched edge and doesn't change any attributes of the second matched edge. I think the easiest approach would be to convert the graphs into a data frame and merge them together:

g2 <- graph_from_adjacency_matrix(edge_attr_mat, 'undirected', weighted = T)
V(g2)$name <-c ("A", "B", "C", "D")

gdf <- as_data_frame(g)
g2df <- as_data_frame(g2)

#dplyr also has function as_data_frame
gdf %>%
  dplyr::left_join(g2df) %>%
  graph_from_data_frame(F)