Networks in igraph

library(igraph)
## 
## Attaching package: 'igraph'
## The following objects are masked from 'package:stats':
## 
##     decompose, spectrum
## The following object is masked from 'package:base':
## 
##     union
# Create an undirected graph w/3 edges
g1 <- graph( edges=c(1,2, 2,3, 3, 1), n=3, directed=F ) 

# Plot the network
plot(g1) 

# Spot Check graph
class(g1)
## [1] "igraph"
g1
## IGRAPH U--- 3 3 -- 
## + edges:
## [1] 1--2 2--3 1--3
# Now with 10 vertices, and directed by default:
g2 <- graph( edges=c(1,2, 2,3, 3, 1), n=10 )
plot(g2)   

g2
## IGRAPH D--- 10 3 -- 
## + edges:
## [1] 1->2 2->3 3->1
g3 <- graph( c("John", "Jim", "Jim", "Jill", "Jill", "John")) # named vertices
# When the edge list has vertex names, the number of nodes is not needed
plot(g3)

g4 <- graph( c("John", "Jim", "Jim", "Jack", "Jim", "Jack", "John", "John"), 
             isolates=c("Jesse", "Janis", "Jennifer", "Justin") )  
# In named graphs we can specify isolates by providing a list of their names.

plot(g4, edge.arrow.size=.5, vertex.color="gold", vertex.size=15, 
     vertex.frame.color="gray", vertex.label.color="black", 
     vertex.label.cex=0.8, vertex.label.dist=2, edge.curved=0.2) 

plot(graph_from_literal(a---b, b---c)) # the number of dashes doesn't matter

plot(graph_from_literal(a--+b, b+--c))

plot(graph_from_literal(a+-+b, b+-+c)) 

plot(graph_from_literal(a:b:c---c:d:e))

gl <- graph_from_literal(a-b-c-d-e-f, a-g-h-b, h-e:f:i, j)
plot(gl)

2.2 Edge, vertex, and network attributes

E(g4) # The edges of the object
## + 4/4 edges (vertex names):
## [1] John->Jim  Jim ->Jack Jim ->Jack John->John
V(g4) # The vertices of the object
## + 7/7 vertices, named:
## [1] John     Jim      Jack     Jesse    Janis    Jennifer Justin
g4[] # You can also examine the network matrix directly
## 7 x 7 sparse Matrix of class "dgCMatrix"
##          John Jim Jack Jesse Janis Jennifer Justin
## John        1   1    .     .     .        .      .
## Jim         .   .    2     .     .        .      .
## Jack        .   .    .     .     .        .      .
## Jesse       .   .    .     .     .        .      .
## Janis       .   .    .     .     .        .      .
## Jennifer    .   .    .     .     .        .      .
## Justin      .   .    .     .     .        .      .
g4[1,] 
##     John      Jim     Jack    Jesse    Janis Jennifer   Justin 
##        1        1        0        0        0        0        0
# Add attributes to the network, vertices, or edges:
V(g4)$name # automatically generated when we created the network.
## [1] "John"     "Jim"      "Jack"     "Jesse"    "Janis"    "Jennifer"
## [7] "Justin"
V(g4)$gender <- c("male", "male", "male", "male", "female", "female", "male")
E(g4)$type <- "email" # Edge attribute, assign "email" to all edges
E(g4)$weight <- 10    # Edge weight, setting all existing edges to 10

# Examine attributes
edge_attr(g4)
## $type
## [1] "email" "email" "email" "email"
## 
## $weight
## [1] 10 10 10 10
vertex_attr(g4)
## $name
## [1] "John"     "Jim"      "Jack"     "Jesse"    "Janis"    "Jennifer"
## [7] "Justin"  
## 
## $gender
## [1] "male"   "male"   "male"   "male"   "female" "female" "male"
graph_attr(g4)
## named list()
# Another way to set attributes (you can similarly use set_edge_attr(), set_vertex_attr(), etc.):

g4 <- set_graph_attr(g4, "name", "Email Network")
g4 <- set_graph_attr(g4, "something", "A thing")
graph_attr_names(g4)
## [1] "name"      "something"
graph_attr(g4, "name")
## [1] "Email Network"
graph_attr(g4)
## $name
## [1] "Email Network"
## 
## $something
## [1] "A thing"
g4 <- delete_graph_attr(g4, "something")
graph_attr(g4)
## $name
## [1] "Email Network"
plot(g4, edge.arrow.size=.5, vertex.label.color="black", vertex.label.dist=1.5,
     vertex.color=c( "pink", "skyblue")[1+(V(g4)$gender=="male")] ) 

g4s <- simplify( g4, remove.multiple = T, remove.loops = F, 
                 edge.attr.comb=c(weight="sum", type="ignore") )
plot(g4s, vertex.label.dist=1.5)

g4s
## IGRAPH DNW- 7 3 -- Email Network
## + attr: name (g/c), name (v/c), gender (v/c), weight (e/n)
## + edges (vertex names):
## [1] John->John John->Jim  Jim ->Jack

The description of an igraph object starts with up to four letters:

  • D or U, for a directed or undirected graph
  • N for a named graph (where nodes have a name attribute)
  • W for a weighted graph (where edges have a weight attribute)
  • B for a bipartite (two-mode) graph (where nodes have a type attribute)

The two numbers that follow (7 5) refer to the number of nodes and edges in the graph. The description also lists node & edge attributes, for example:

  • (g/c) - graph-level character attribute
  • (v/c) - vertex-level character attribute
  • (e/n) - edge-level numeric attribute

Specific graphs and graph models

Empty Graph

eg <- make_empty_graph(40)
plot(eg, vertex.size=10, vertex.label=NA)

Full Graph

fg <- make_full_graph(40)
plot(fg, vertex.size=10, vertex.label=NA)

Simple star graph

st <- make_star(40)
plot(st, vertex.size=10, vertex.label=NA) 

Tree graph

tr <- make_tree(40, children = 3, mode = "undirected")
plot(tr, vertex.size=10, vertex.label=NA) 

Ring graph

rn <- make_ring(40)
plot(rn, vertex.size=10, vertex.label=NA)

Erdos-Renyi random graph model

(‘n’ is number of nodes, ‘m’ is the number of edges).

er <- sample_gnm(n=100, m=40) 
plot(er, vertex.size=6, vertex.label=NA)

Watts-Strogatz small-world model

sw <- sample_smallworld(dim=2, size=10, nei=1, p=0.1)
plot(sw, vertex.size=6, vertex.label=NA, layout=layout_in_circle)

Barabasi-Albert preferential attachment model for scale-free graphs

ba <-  sample_pa(n=100, power=1, m=1,  directed=F)
 plot(ba, vertex.size=6, vertex.label=NA)

igraph can also give you some notable historical graphs. For instance:

zach <- graph("Zachary") # the Zachary carate club
 plot(zach, vertex.size=10, vertex.label=NA)

Rewiring a graph

each_edge() is a rewiring method that changes the edge endpoints uniformly randomly with a probability prob.

rn.rewired <- rewire(rn, each_edge(prob=0.1))
 plot(rn.rewired, vertex.size=10, vertex.label=NA)

Rewire to connect vertices to other vertices at a certain distance.

rn.neigh = connect.neighborhood(rn, 5)
 plot(rn.neigh, vertex.size=8, vertex.label=NA) 

Combine graphs (disjoint union, assuming separate vertex sets): %du%

plot(rn, vertex.size=10, vertex.label=NA) 

plot(tr, vertex.size=10, vertex.label=NA) 

plot(rn %du% tr, vertex.size=10, vertex.label=NA)