1

I have a dataset containing the edge list of a weighted undirected graph. My dataset contains multiple components.

Now, I am trying to connect the components of the graph. My graph contains 4 components. Actually, I want to connect them any edge of 1 component with any edge of another component and would like to give any weight of this edge.

graph1 <- graph_from_data_frame(g, directed = FALSE)
E(graph1)$weight <- is.numeric(g$new_ssp)
plot(graph1, vertex.label = V(graph1)$name)
is_weighted(graph1)
cl <- components(graph1)

Also, I can find the membership of the graph

connected_components <- lapply(seq_along(cl$csize)[cl$csize > 1], function(x) 
  V(graph1)$name[cl$membership %in% x])

Now, could you give me any idea how can I connect all components? Is it possible?

Reproducible Data:

g <- structure(list(query = structure(c(1L, 1L, 1L, 2L, 2L, 3L, 4L, 
                                   5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L), .Label = c("ID_00104", 
                                                                                                       "ID_00136", "ID_00169", "ID_00178", "ID_00180"), class = "factor"), 
               target = structure(c(16L, 19L, 20L, 1L, 9L, 9L, 6L, 11L, 
                                    13L, 15L, 4L, 8L, 10L, 14L, 2L, 3L, 5L, 7L, 12L, 17L, 18L
               ), .Label = c("ID_00169", "ID_00288", "ID_00324", "ID_00394", 
                             "ID_00663", "ID_00790", "ID_00846", "ID_00860", "ID_00910", "ID_00959", 
                             "ID_01013", "ID_01047", "ID_01130", "ID_01222", "ID_01260", "ID_06663", 
                             "ID_06781", "ID_06786", "ID_06791", "ID_09099"), class = "factor"), 
               new_ssp = c(0.654172560113154, 0.919096895578551, 0.925821596244131, 
                           0.860406091370558, 0.746376811594203, 0.767195767195767, 
                           0.830379746835443, 0.661577608142494, 0.707520891364902, 
                           0.908193484698914, 0.657118786857624, 0.687664041994751, 
                           0.68586387434555, 0.874513618677043, 0.836646499567848, 0.618361836183618, 
                           0.684163701067616, 0.914728682170543, 0.876297577854671, 
                           0.732707087959009, 0.773116438356164)), row.names = c(NA, 
                                                                                 -21L), class = "data.frame")
0Knowledge
  • 747
  • 3
  • 14

1 Answers1

1

Try the code below

graph2 <- with(
  stack(membership(cl)),
  add.edges(
    graph1,
    c(combn(sapply(split(ind, values), sample, size = 1), 2)),
    weight = runif(choose(cl$no, 2))
  )
)

where a full connections among all components is given as below enter image description here


You can check the weights of edges of graph2

> E(graph2)
+ 27/27 edges from 31a7614 (vertex names):
 [1] ID_00104--ID_06663 ID_00104--ID_06791 ID_00104--ID_09099 ID_00136--ID_00169
 [5] ID_00136--ID_00910 ID_00169--ID_00910 ID_00178--ID_00790 ID_00180--ID_01013
 [9] ID_00180--ID_01130 ID_00180--ID_01260 ID_00180--ID_00394 ID_00180--ID_00860
[13] ID_00180--ID_00959 ID_00180--ID_01222 ID_00180--ID_00288 ID_00180--ID_00324
[17] ID_00180--ID_00663 ID_00180--ID_00846 ID_00180--ID_01047 ID_00180--ID_06781
[21] ID_00180--ID_06786 ID_00136--ID_06663 ID_00178--ID_06663 ID_06663--ID_01013
[25] ID_00136--ID_00178 ID_00136--ID_01013 ID_00178--ID_01013

> E(graph2)$weight
 [1] 0.6541726 0.9190969 0.9258216 0.8604061 0.7463768 0.7671958 0.8303797
 [8] 0.6615776 0.7075209 0.9081935 0.6571188 0.6876640 0.6858639 0.8745136
[15] 0.8366465 0.6183618 0.6841637 0.9147287 0.8762976 0.7327071 0.7731164
[22] 0.3098355 0.5842953 0.7397926 0.7337629 0.7643245 0.8331742

If you want to see edge list, you can use as_data_frame, e.g.,

> as_data_frame(graph2)
       from       to   new_ssp    weight
1  ID_00104 ID_06663 0.6541726 0.6541726
2  ID_00104 ID_06791 0.9190969 0.9190969
3  ID_00104 ID_09099 0.9258216 0.9258216
4  ID_00136 ID_00169 0.8604061 0.8604061
5  ID_00136 ID_00910 0.7463768 0.7463768
6  ID_00169 ID_00910 0.7671958 0.7671958
7  ID_00178 ID_00790 0.8303797 0.8303797
8  ID_00180 ID_01013 0.6615776 0.6615776
9  ID_00180 ID_01130 0.7075209 0.7075209
10 ID_00180 ID_01260 0.9081935 0.9081935
11 ID_00180 ID_00394 0.6571188 0.6571188
12 ID_00180 ID_00860 0.6876640 0.6876640
13 ID_00180 ID_00959 0.6858639 0.6858639
14 ID_00180 ID_01222 0.8745136 0.8745136
15 ID_00180 ID_00288 0.8366465 0.8366465
16 ID_00180 ID_00324 0.6183618 0.6183618
17 ID_00180 ID_00663 0.6841637 0.6841637
18 ID_00180 ID_00846 0.9147287 0.9147287
19 ID_00180 ID_01047 0.8762976 0.8762976
20 ID_00180 ID_06781 0.7327071 0.7327071
21 ID_00180 ID_06786 0.7731164 0.7731164
22 ID_06791 ID_00910        NA 0.5680686
23 ID_00178 ID_06791        NA 0.6278790
24 ID_06791 ID_00288        NA 0.8059711
25 ID_00178 ID_00910        NA 0.2578959
26 ID_00910 ID_00288        NA 0.6189977
27 ID_00178 ID_00288        NA 0.6594792
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
  • Thank you very much. Could you tell me, what is `size=1`? As, my previous graph is `weighted` and it has `edge weight`, now the near one also weighted (I checked the `is_weighted(graph2)` function). But, could you tell me, how can I check the weight of the new edge? – 0Knowledge Mar 16 '21 at 23:38
  • @Akib62 `size=1` is an argument from `sample`, which randomly selects `1` from each component when using `sapply` over `cl`. I didn't assign any weight to newly added edges. but it is easy to do. You can try `replace(E(graph2)$weight, is.na(E(graph2)$weight),1)` to assign all new edges with weight `1`. for example. – ThomasIsCoding Mar 16 '21 at 23:44
  • @Akib62 I updated my solution, which assign random weights to newly added edges. – ThomasIsCoding Mar 16 '21 at 23:52
  • Many many thanks. That's mean, I do not need to write this portion of my code `connected_components <- lapply(seq_along(cl$csize)[cl$csize > 1], function(x) V(graph1)$name[cl$membership %in% x])`? As you are taking membership from `cl`. However, when I am trying to generate the edge list of the new graph I am getting only the edge list not the weight. Could you tell me how can I get the edge_list with weight? I am trying `graph2_edge <- as_edgelist(graph2, names = TRUE)` – 0Knowledge Mar 16 '21 at 23:54
  • @Akib62 Try `as_data_frame(graph2)` – ThomasIsCoding Mar 16 '21 at 23:58
  • Oops, getting error `Error in as.data.frame.default(value, stringsAsFactors = FALSE) : cannot coerce class ‘"igraph"’ to a data.frame In addition: Warning message: `as_data_frame()` is deprecated as of tibble 2.0.0. Please use `as_tibble()` instead. The signature and semantics have changed, see `?as_tibble`.` – 0Knowledge Mar 17 '21 at 00:00
  • @Akib62 Try `igraph::as_data_frame` – ThomasIsCoding Mar 17 '21 at 00:03
  • Many many thanks. I am curious, what is the difference between `igraph::as_data_frame`and `as_data_frame` as I already loaded the library! – 0Knowledge Mar 17 '21 at 00:07
  • @Akib62 It may have collisions with other loaded libraries and masked. You may need to specify the namespace to play it safe. – ThomasIsCoding Mar 17 '21 at 00:08
  • Great. Today, I learned a lot from you. Thank you again – 0Knowledge Mar 17 '21 at 00:09
  • Ok, if I want to add the edge weight `anything` instead of `1` then what I have to change in the code? AND the code is adding weight `randomly` not `1`! – 0Knowledge Mar 17 '21 at 00:12
  • 1
    @Akib62 See the argument of `add.edges` in my answer – ThomasIsCoding Mar 17 '21 at 00:13
  • If you have some time, please check this question, I will grateful (https://stackoverflow.com/questions/66826023/how-to-add-a-edges-between-component-of-a-graph-in-igraph-r) – 0Knowledge Mar 27 '21 at 00:50