R igraph vertex coloring - r

I'm trying to color the vertices according to the dummy variable [color_thresh]. Data looks like the following:
I have tried several suggested methods, but the closest (and simplest) I can do produces the following:
Here is my code for reproducing data and the graph above:
library(igraph)
library(data.tree)
Level_0 = c("TAC_310B_124","TAC_310B_124","TAC_310B_124","TAC_310B_124","TAC_310B_124","TAC_310B_124","TAC_310B_124","TAC_310B_124","TAC_310B_124")
Level_1 = c("","SC_776E_86","SS_A66D_9","SC_776E_86","SC_776E_86","SC_776E_86","SC_776E_86","SC_776E_86","SC_776E_86")
Level_2 = c("","","","TGW_1DD0_42","TGW_1DD0_42","TGW_1DD0_42","TGW_1DD0_42","TGW_1DD0_42","TGW_1DD0_42")
Level_3 = c("","","","","CORB_F2E4_17","CORB_F2E4_22","CORB_AE16_10921","CORB_AE16_10921","CORB_AE16_10921")
Level_4 = c("","","","","","","","CORB_D81E_45","CORB_D81E_45")
Level_5 = c("","","","","","","","","SC_B949_3156")
color_thresh = c(1,0,0,0,0,0,1,0,1)
dataset <- data.frame(Level_0,Level_1,Level_2,Level_3,Level_4,Level_5,color_thresh)
dataset$pathString <- paste(dataset$Level_0,
dataset$Level_1,
dataset$Level_2,
dataset$Level_3,
dataset$Level_4,
dataset$Level_5,
sep = "/")
g <- as.Node(dataset)
g <- as.igraph(g, directed=TRUE)
V(g)$color <- ifelse(dataset$color_thresh==1, "red", "green")
plot.igraph(g, vertex.label.color="black", vertex.label.dist=0, vertex.label.family="Helvetica", vertex.frame.color="white", vertex.size=25, layout=layout_as_tree)
The colors change when i sort the data frame by [color_thresh], but still doesn't give me the right colors.
Any comments helping me to understand how the conditional coloring works is much appreciated! Thank you so much in advance.

Here is an approach:
g <- as.Node(dataset)
g <- as.igraph(g, directed=TRUE)
Check how the nodes are sorted
g_data <- get.data.frame(g, what="vertices")$name
see how the nodes are sorted in your data:
data_vert <- apply(dataset[1:6], 1, function(x) tail(x[x!=""], 1))
Sort data according to nodes and apply color
V(g)$color <- ifelse(dataset$color_thresh[match(g_data , data_vert)] == 1, "red", "green")
plot.igraph(g, vertex.label.color="black", vertex.label.dist=0, vertex.label.family="Helvetica", vertex.frame.color="white", vertex.size=25, layout=layout_as_tree)
Is that the correct color coding?
another approach would be explicitly stating which nodes should have which color:
g <- as.Node(dataset)
g <- as.igraph(g, directed = TRUE)
V(g)$color <- "green"
V(g)["TAC_310B_124"]$color <- "red"
V(g)["SC_B949_3156" ]$color <- "red"
V(g)["CORB_AE16_10921"]$color <- "red"
same output image

Related

Overriding "Non-Existent Components" in a Loop

I have the following network graph:
library(tidyverse)
library(igraph)
set.seed(123)
n=15
data = tibble(d = paste(1:n))
relations = tibble(
from = sample(data$d),
to = lead(from, default=from[1]),
)
graph = graph_from_data_frame(relations, directed=T, vertices = data)
V(graph)$color <- ifelse(data$d == relations$from[1], "red", "orange")
plot(graph, layout=layout.circle, edge.arrow.size = 0.2)
I learned how to remove all the "edges" in this graph:
g <- graph-E(graph)
plot(g)
Now, I am trying to do this same thing, but using a "loop" instead:
for (i in 1:15)
for (j in 1:15) {
graph <- graph - edge(paste0(i, "|", j))
}
But I think the problem is that the above code is trying to delete "edges" that exist, and this code does not have the ability to "skip" (override) an instance when it is commanded to delete a non-existing edge:
Error in delete_edges(e1, unlist(e2, recursive = FALSE)) :
At iterators.c:1828 : Cannot create iterator, invalid edge id, Invalid vertex id
Is there a way to instruct this "loop" to "skip" every instances where two edges do not have a connection and to continue until the loop is done?
Thank you!
I don't know why you want to run a for loop, but please find below a possible solution using the as_edgelist() function from the igraph library.
Reprex
Your data
library(igraph)
library(dplyr)
set.seed(123)
n=15
data = tibble(d = paste(1:n))
relations = tibble(
from = sample(data$d),
to = lead(from, default=from[1]),
)
graph = graph_from_data_frame(relations, directed=T, vertices = data)
V(graph)$color <- ifelse(data$d == relations$from[1], "red", "orange")
plot(graph, layout=layout.circle, edge.arrow.size = 0.2)
Suggested code
edgelist <- as_edgelist(graph, names = TRUE)
for (i in 1:15) {
graph <- graph - edge(paste0(edgelist[i,1], "|", edgelist[i,2]))
}
plot(graph)
Created on 2022-02-24 by the reprex package (v2.0.1)

Multi-panel network figure using a loop?

I'm trying to make a multipanel figure with networks in the igraph package. I'd like 2 rows, each with 3 networks. I need to be able to save the figure as a PNG and I'd like to label them each A:F in one of the corners. I've tried to do this in a loop but only one network appears in the figures. I need the V(nw)$x<- y and E(nw)$x<- y code in the loop to make my networks come out properly. My networks are in a list().
I've made a small sample of the code I've tried, I would like to avoid doing it without a loop if I can. Thanks in advance.
srs_1nw <- graph("Zachary")
srs_2nw <- graph("Heawood")
srs_3nw <- graph("Folkman")
srs_1c <- cluster_fast_greedy(srs_1nw)
srs_2c <- cluster_fast_greedy(srs_2nw)
srs_3c <- cluster_fast_greedy(srs_3nw)
listofsrs_nws <- list(srs_1nw,srs_2nw,srs_3nw)
listofsrs_cs <- list(srs_1c,srs_2c,srs_3c)
colours <- c("red","blue","green","yellow")
par(mfrow=c(2,3))
for (i in length(listofsrs_nws)) {
c<-listofsrs_cs[[i]]
nw<-listofsrs_nws[[i]]
V(nw)$size <- log(strength(nw))*6 # weighted nodes
E(nw)$arrow.size <- 2 # arrow size
c.colours <- colours[membership(c)]
plot(c, nw, col = c.colours,
mark.col = adjustcolor(colours, alpha.f = 0.4),
mark.border = adjustcolor(colours, alpha.f = 1),
vertex.frame.width = 5, edge.curved = .15)
}
We can use mapply like below
mapply(function(c, nw) {
V(nw)$size <- log(strength(nw)) * 6 # weighted nodes
E(nw)$arrow.size <- 2 # arrow size
c.colours <- colours[membership(c)]
plot(c, nw,
col = c.colours,
mark.col = adjustcolor(colours, alpha.f = 0.4),
mark.border = adjustcolor(colours, alpha.f = 1),
vertex.frame.width = 5, edge.curved = .15
)
}, listofsrs_cs, listofsrs_nws)

R igraph cluster nodes with the same colour (feature)

# example data
library(igraph)
links <- cbind.data.frame(from = rep("A", 6),
to = LETTERS[1:6],
weight = rep((1:3), each =2))
nodes <- nodes <- cbind.data.frame(id = LETTERS[1:6],
feature = rep((1:3), each =2))
net <- graph_from_data_frame(d = links, vertices = nodes, directed = T)
V(net)$color <- V(net)$feature
plot(net, vertex.size=30, edge.arrow.size = 0)
This is what I get:
What I want is to cluster the same colored nodes together, something similar as shown in the figure below. How can I do it?
Maybe the option mark.groups in plot could help
plot(net,mark.groups = split(V(net)$name,V(net)$color))
which gives

Setting subgraph/cluster attributes in Rgraphviz

I want to plot a graph via Rgraphviz but I can't handle the design attributes of the clusters that I set.
There are similar questions already on SO and elsewhere but none has a real minimal working example and none of them is answered. So I want to try to ask a complete question to receive a complete answer. As an introduction to the package, I read the paper "How To Plot A Graph Using Rgraphviz" by Gentry, Gentleman, and Huber.
My example network:
library(Rgraphviz)
set.seed(123)
V <- letters[1:6]
M <- 1:4
g1 <- randomGraph(V, M, 0.2)
If I want to plot it, I can easily give it some attributes via a list:
attributes <- list(node = list(shape = "rectangle", fixedsize = FALSE),
graph = list(layout = "dot", bgcolor = "transparent"))
plot(g1, attrs = attributes )
Plotting it via plot(g1) gives the following result:
Now I want to define two clusters/subgraphs. This can be done this way:
sg1= subGraph(c("a", "e", "f"), g1)
sg2= subGraph(c("b", "c", "d"), g1)
subGList <- vector(mode = "list", length = 2)
subGList[[1]] <- list(graph = sg1, cluster = TRUE)
subGList[[2]] <- list(graph = sg2, cluster = TRUE)
Plotting the graph again now including a subGlist argument:
plot(g1, attrs = attributes , subGList = subGList)
So, obviously, there has been a change in the setting and even though it would be convenient having the clusters a little bit more separated, the result is ok.
Now if I want to define cluster-specific styles or try to have them framed, I start having problems. According to page 4 of the mentioned introductory paper one can simply add an element called attrs to the sublists of subGlist.
To my understanding, it should work this way:
subGList[[1]] <- list(graph = sg1,
cluster = TRUE,
attrs = c(fontcolor = "red"))
plot(g1, attrs = attrs, subGList = subGList)
Unfortunately, it doesn't. As mentioned, I would like to frame my clusters (similar to this SO post) but as I can't even handle the fontcolors of the clusters, I think I make a somehow more fundamental mistake.
My complete code:
library(Rgraphviz)
set.seed(123)
V <- letters[1:6]
M <- 1:4
g1 <- randomGraph(V, M, 0.2)
attributes <- list(node = list(shape = "rectangle", fixedsize = FALSE),
graph = list(layout = "dot", bgcolor = "transparent"))
#plot(g1, attrs = attributes )
sg1= subGraph(c("a", "e", "f"), g1)
sg2= subGraph(c("b", "c", "d"), g1)
subGList <- vector(mode = "list", length = 2)
subGList[[1]] <- list(graph = sg1, cluster = TRUE)
subGList[[2]] <- list(graph = sg2, cluster = TRUE)
#plot(g1, attrs = attributes , subGList = subGList)
subGList[[1]] <- list(graph = sg1,
cluster = TRUE,
attrs = c(fontcolor = "red"))
plot(g1, attrs = attrs, subGList = subGList)
I hope someone can help! Thank you

Show edge attributes as label with igraph

I am using igraph in R for network analysis. I want to display an edge attribute on each line in the plot. An example is below
df <- data.frame(a = c(0,1,2,3,4),b = c(3,4,5,6,7))
nod <- data.frame(node = c(0:7),wt = c(1:8))
pg <- graph_from_data_frame(d = df, vertices = nod,directed = F)
plot(pg)
I want the value of the "wt" feature to show up between each node on the line, or preferably, in a little gap where the line breaks.
Is it possible to make this happen?
Use the parameter edge.label to assign labels of the edges, I used - probably wrong - nod$wt. Of course, you could assign other labels.
You could use the following code:
# load the package
library(igraph)
# your code
df <- data.frame(a = c(0,1,2,3,4),b = c(3,4,5,6,7))
nod <- data.frame(node = c(0:7),wt = c(1:8))
pg <- graph_from_data_frame(d = df, vertices = nod,directed = F)
# plot function with edge.label added
plot(pg, edge.label = nod$wt)
Please, let me know whether this is what you want.

Resources