Collapsing graph by clusters in igraph - r

I want to collapse a graph into its respective communities/clusters. Let me illustrate this with the following toy example:
set.seed(123)
#toy graph
g <- barabasi.game(10) %>%
as.undirected()
#identify communities
c_g <- fastgreedy.community(g)
There are three communities, as seen in the following graph.
I want to reduce the collapse the vertices so that vertices in the resulting graph correspond to the membership of the previous vertices. See the graph.
I'm new to the igraph package and I'm not familiar with the best way of dealing with igraph objects.

You could try contract:
library(igraph)
set.seed(123)
g <- barabasi.game(10) %>% as.undirected()
c_g <- fastgreedy.community(g)
V(g)$name <- letters[1:vcount(g)]
g2 <- contract(g, membership(c_g), vertex.attr.comb=toString)
par(mfrow=c(1,2))
plot(g, vertex.color=membership(c_g))
plot(simplify(g2), vertex.color=1:vcount(g2))

Related

Subset igraph plot in using activate function in R

I am trying to subset an igraph plot to display certain nodes based on a given vertex attribute. I have to subset them in the plot output to preserve the layout for the vertices. My code is the following:
plot.igraph(graph, layout=lo, vertex.label=NA, rescale=T, vertex.size = 4) %>%
tidygraph::activate(nodes) %>%
filter(period == 1)
But I receive the following error:
Error in UseMethod("activate") :
no applicable method for 'activate' applied to an object of class "NULL"
How can I subset the graph based on the vertex attribute "V(graph)$period", maintaining the vertices' layout?
Observe that class(plot(graph)) returns NULL.
Update, calculate subset as follows.
## Random example.
set.seed(20)
g <- make_ring(20)
V(g)$period <- sample(2, vcount(g), replace=TRUE)
V(g)$name <- V(g)
## Calculate subset of vertices
## and plot subgraph.
vvv <- V(g)[which(V(g)$period==1)]
g2 <- subgraph(g, vvv)
plot(g2)

group variables and color by type R igraph

I have a graph where I need the vertices to be in name, with a different color due to the type of data (stock, forex and commodities)... I don't understand how to do it...
in this post igraph group vertices based on community something similar is done... I need not circles, only letters and that they have a different color according to the type of data that is...
library(Hmisc) # For correlation matrix
library(corrplot) # For correlation matrix
library("Spillover")
library(readxl)
library("xts")
library("zoo") #
library("ggplot2")
library("nets")
library("MASS")
library("igraph")
library("reshape") # For "melt" function/cluster network
library("writexl")
# We compute the dynamic interdependence. Direct edges denoted as Granger causality linkages
# We compute the contemporaneous interdependence. Indirect edges denoted as Partial correlation linkages
stock <- table[1:55, 1:55]
forex <- table[56:95, 56:95]
commodities <- table[96:116, 96:116]
dim(stock); dim(forex); dim(commodities)
View(stock);
View(forex);
View(commodities)
# Full network
network.spill <- graph.adjacency(table, mode='directed')
degree <- degree(network.spill) # number of adjacent edges
between <- betweenness(network.spill)
close <- closeness(network.spill, mode = "all")
autorsco <- authority.score(network.spill)$vector
eccentry <- eccentricity(network.spill, mode = "all")
measures <- cbind(as.matrix(degree), as.matrix(between), as.matrix(close), as.matrix(autorsco), as.matrix(eccentry))
View(measures)
V(network.spill)[which(network.spill_forex)]$color="red"
V(network.spill)$size <- round((degree-min(degree))/(max(degree)-min(degree))) # To create vertex
V(network.spill)$shape <- "sphere"
E(network.spill)$name=1:116
# For stock returns layout_nicely(network.spill)
par(mfcol = c(1, 1))
plot( network.spill, layout = layout_nicely(network.spill), vertex.color = c("gold"), vertex.label.cex=0.6,
vertex.size = autorsco*2,edge.curved = 0.2, edge.arrow.mode=0.5,edge.arrow.size=1.5) # To make the chart

Multigraph from two simple graphs in igraph?

How to get a multigraph from two or more simple graphs in R igraph?
G <- graph_from_literal(1-2:3-4-5:6)
E(G)$at <- rep.int("a",6)
G2 <- graph_from_literal(6-7-5-4)
E(G2)$at <- c("b","b","b")
G3 <- graph.union(G, G2)
E(G3)$at_1
E(G3)$at_2
is.simple(G3)
plot(G3)
Note that both graphs have an edge between vertices 4 and 5, I would expect a multigraph as a result, rather than a simple graph.
There is another option instead of graph.union?
Thanks
Herewith an elaboration of Szabolcs's suggestion.
DF3 <- rbind(as_data_frame(G), as_data_frame(G2))
G3b <- graph_from_data_frame(DF3, directed=FALSE)
dev.new()
plot(G3b, edge.color=ifelse(E(G3b)$at == "a", "black", "red"), edge.label=E(G3b)$at)

Create bipartite graph in R?

So this question has been asked here and here... but I cant seem to adapt it to my problem. I am trying to create a bipartite graph using the igraph package in R, that looks something like this:
The code im using to try this is:
# create all pairs and turn into vector for graph edges
pairs <- expand.grid(1:6, 1:6) # create all pairs
pairs <- pairs[!pairs$Var1 == pairs$Var2, ] # remove matching rows
ed <- as.vector(t(pairs)) # turn into vecotr
# create graph
g <- make_empty_graph(n = 6)
g <- add_edges(graph = g, edges = ed)
plot(g)
This will a create a graph... but im trying to make it resemble the graph in the image, with, say, (1,2,3) on the top and (4,5,6) on the bottom.
I tried using make_bipartite_graph() and layout_as_bipartite... but I cant seem to get it to work... any suggestions?
If the graph is created straight from the data.frame it will not be a bipartite graph.
library(igraph)
g <- graph_from_data_frame(df)
is.bipartite(g)
#[1] FALSE
But it will be a bipartite graph if created from the incidence matrix.
tdf <- table(df)
g <- graph.incidence(tdf, weighted = TRUE)
is.bipartite(g)
#[1] TRUE
Now plot it.
colrs <- c("green", "cyan")[V(g)$type + 1L]
plot(g, vertex.color = colrs, layout = layout_as_bipartite)

How to extract both node names and their eigenvector centralities in a datatable

I need to create a datatable with both node names and their eigenvector centralities but the problem is that I cannot extract the node names and I use:
#CENTRALITY
library(igraph)
library(magrittr)
library(visNetwork)
library(data.table)
library(geomnet)
#Load dataset
data(lesmis)
#Nodes
nodes <- as.data.frame(lesmis[2])
colnames(nodes) <- c("id", "label")
#id has to be the same like from and to columns in edges
nodes$id <- nodes$label
#Edges
edges <- as.data.frame(lesmis[1])
colnames(edges) <- c("from", "to", "width")
#Create graph for Louvain
graph <- graph_from_data_frame(edges, directed = FALSE)
graph <- simplify(graph)
library(DT)
ev<-evcent(graph)$vector
datatable(ev)
It seems like you already have almost everything done here. Unless I am misunderstanding, this finishes off your request.
## create a data.frame with required columns
nodes$ev = evcent(graph)$vector
## if you really want a data.table
nodes.dt = as.data.table(nodes)

Resources