install.packages('igraph')
library(igraph)
# Working with Network Data ---------------------------------------------------
# Create networks
g1 <- make_graph(edges=c(1,2, 2,3, 3,1), n=3)
plot(g1)

g2 <- make_graph(edges=c(1,2, 2,3, 3,1), n=10, directed = FALSE)
plot(g2)

g3 <- make_graph(edges=c("John","Jim", "Jim","Jack", "Jim","Jack", "John","John"),
isolates=c("Jesse", "Janis", "Jennifer", "Justin"))
plot(g3)
# Edge, vertex and network attributes
E(g3) # view edges
## + 4/4 edges from 1973f01 (vertex names):
## [1] John->Jim Jim ->Jack Jim ->Jack John->John
V(g3)
## + 7/7 vertices, named, from 1973f01:
## [1] John Jim Jack Jesse Janis Jennifer Justin
g3[] # view the network (in matrix)

## 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 . . . . . . .
V(g3)$name # retrieve existing vertex attribute
## [1] "John" "Jim" "Jack" "Jesse" "Janis" "Jennifer"
## [7] "Justin"
V(g3)$gender <- c("male","male","male","male","female","female","male") # add v. attri.
E(g3)$type <- "email" # add edge attribute
E(g3)$weight <- c(2,5,1,10) # change edge weight
vertex_attr(g3) # list vertex attributes
## $name
## [1] "John" "Jim" "Jack" "Jesse" "Janis" "Jennifer"
## [7] "Justin"
##
## $gender
## [1] "male" "male" "male" "male" "female" "female" "male"
edge_attr(g3)
## $type
## [1] "email" "email" "email" "email"
##
## $weight
## [1] 2 5 1 10
# Network datasets
# data in edgelist
nodes <- read.csv('Dataset1-NODES.csv', header=T, as.is=T)
links <- read.csv('Dataset1-EDGES.csv', header=T, as.is=T)
head(nodes)
## id media media.type type.label audience.size
## 1 s01 NY Times 1 Newspaper 20
## 2 s02 Washington Post 1 Newspaper 25
## 3 s03 Wall Street Journal 1 Newspaper 30
## 4 s04 USA Today 1 Newspaper 32
## 5 s05 LA Times 1 Newspaper 20
## 6 s06 New York Post 1 Newspaper 50
head(links)
## from to weight type
## 1 s01 s02 10 hyperlink
## 2 s01 s02 12 hyperlink
## 3 s01 s03 22 hyperlink
## 4 s01 s04 21 hyperlink
## 5 s04 s11 22 mention
## 6 s05 s15 21 mention
nrow(nodes); length(unique(nodes$id))
## [1] 17
## [1] 17
nrow(links); nrow(unique(links[,c("from", "to")])) # a few duplicated pairs
## [1] 52
## [1] 49
# combine same pairs by suming up their weights
links <- aggregate(links[,3], links[,-3], sum) # sum weights by from, to, type
links <- links[order(links$from, links$to),]
head(links,3)
## from to type x
## 4 s01 s02 hyperlink 22
## 6 s01 s03 hyperlink 22
## 11 s01 s04 hyperlink 21
colnames(links)[4] <- "weight"
rownames(links) <- NULL
# convert to igraph object
net <- graph_from_data_frame(d=links, vertices=nodes, directed=T)
class(net)
## [1] "igraph"
net
## IGRAPH 1a86092 DNW- 17 49 --
## + attr: name (v/c), media (v/c), media.type (v/n), type.label
## | (v/c), audience.size (v/n), type (e/c), weight (e/n)
## + edges from 1a86092 (vertex names):
## [1] s01->s02 s01->s03 s01->s04 s01->s15 s02->s01 s02->s03 s02->s09
## [8] s02->s10 s03->s01 s03->s04 s03->s05 s03->s08 s03->s10 s03->s11
## [15] s03->s12 s04->s03 s04->s06 s04->s11 s04->s12 s04->s17 s05->s01
## [22] s05->s02 s05->s09 s05->s15 s06->s06 s06->s16 s06->s17 s07->s03
## [29] s07->s08 s07->s10 s07->s14 s08->s03 s08->s07 s08->s09 s09->s10
## [36] s10->s03 s12->s06 s12->s13 s12->s14 s13->s12 s13->s17 s14->s11
## [43] s14->s13 s15->s01 s15->s04 s15->s06 s16->s06 s16->s17 s17->s04
plot(net)

net <- simplify(net, remove.loops = T)
# data in matirx
links.m <- read.csv('Dataset1-EDGES-mat.csv', header=T, row.names=1)
head(links.m)
## s01 s02 s03 s04 s05 s06 s07 s08 s09 s10 s12 s13 s14 s15 s16 s17 s11
## s01 0 22 22 21 0 0 0 0 0 0 0 0 0 20 0 0 0
## s02 23 0 21 0 0 0 0 0 1 5 0 0 0 0 0 0 0
## s03 21 0 0 22 1 0 0 4 0 2 1 0 0 0 0 0 1
## s04 0 0 23 0 0 1 0 0 0 0 3 0 0 0 0 2 22
## s05 1 21 0 0 0 0 0 0 2 0 0 0 0 21 0 0 0
## s06 0 0 0 0 0 1 0 0 0 0 0 0 0 0 21 21 0
class(links.m)
## [1] "data.frame"
links.m <- as.matrix(links.m)
class(links.m)
## [1] "matrix"
net.m <- graph_from_adjacency_matrix(links.m)
class(net.m)
## [1] "igraph"
# Measure Networks ------------------------------------------------------------
# --- Vertex level: describe nodes --- #
# Centrality
degree(net, mode='in')
## s01 s02 s03 s04 s05 s06 s07 s08 s09 s10 s11 s12 s13 s14 s15 s16 s17
## 4 2 6 4 1 4 1 2 3 4 3 3 2 2 2 1 4
closeness(net, mode='all', weights=NA)
## s01 s02 s03 s04 s05 s06
## 0.03333333 0.03030303 0.04166667 0.03846154 0.03225806 0.03125000
## s07 s08 s09 s10 s11 s12
## 0.03030303 0.02857143 0.02564103 0.02941176 0.03225806 0.03571429
## s13 s14 s15 s16 s17
## 0.02702703 0.02941176 0.03030303 0.02222222 0.02857143
betweenness(net, directed=T, weights=NA)
## s01 s02 s03 s04 s05 s06
## 24.0000000 5.8333333 127.0000000 93.5000000 16.5000000 20.3333333
## s07 s08 s09 s10 s11 s12
## 1.8333333 19.5000000 0.8333333 15.0000000 0.0000000 33.5000000
## s13 s14 s15 s16 s17
## 20.0000000 4.0000000 5.6666667 0.0000000 58.5000000
# --- Graph level: describe network as a whole --- #
# number of nodes and edges
vcount(net)
## [1] 17
ecount(net)
## [1] 48
# average degree
mean(degree(net))
## [1] 5.647059
# degree distribution
net.degrees <- degree(net)
nd.hist <- as.data.frame(table(net.degrees)) # count the freq of each degree
nd.hist[,1] <- as.numeric(nd.hist[,1]) # convert the first column to numbers
plot(nd.hist)

# Density
graph.density(net)
## [1] 0.1764706
# Reciprocity
reciprocity(net)
## [1] 0.4166667
# --- Community Detection --- #
wc <- walktrap.community(net)
dendPlot(wc, mode="hclust")

plot(wc, net)

class(wc)
## [1] "communities"
length(wc)
## [1] 4
membership(wc)
## s01 s02 s03 s04 s05 s06 s07 s08 s09 s10 s11 s12 s13 s14 s15 s16 s17
## 1 1 1 1 1 3 2 2 2 2 1 4 4 4 1 3 3
modularity(wc)
## [1] 0.5972482
# Visualization ---------------------------------------------------------------
plot(net)

# set node & edge options
plot(net, edge.arrow.size=.2, edge.curved=0,
vertex.color='orange', vertex.frame.color='#555555',
vertex.label=V(net)$media, vertex.label.color='black',
vertex.label.cex=.7)

?igraph.plotting # plotting parameters
# set attributes for plotting
# set node colors, size, and labels
colrs <- c('gray50', 'tomato', 'gold')
V(net)$color <- colrs[V(net)$media.type]
V(net)$size <- V(net)$audience.size*0.7
V(net)$label.color <- 'black'
# set edge width, color and arrow size
E(net)$width <- E(net)$weight/6
E(net)$edge.color <- 'gray80'
E(net)$arrow.size <- .2
plot(net)

# adjust some of the settings
V(net)$label <- NA
E(net)$width <- 1+E(net)$weight/12
plot(net)

# the attribute settings can be override
plot(net, edge.color='orange', vertex.color='gray50')

# legend
plot(net)
legend(x=-1.5, y=-1.1, c("Newspaper","Television", "Online News"), pch=21,
col='#777777', pt.bg=colrs, pt.cex=2, cex=.8, bty='n', ncol=1)

# plot with labels only
plot(net, vertex.shape='none', vertex.label=V(net)$media,
vertex.label.font=2, vertex.label.color='gray40',
vertex.label.cex=.7, edge.color='gray85')

# color the edges based on source node color
edge.start <- ends(net, es=E(net), names=F)[,1]
edge.col <- V(net)$color[edge.start]
plot(net, edge.color=edge.col, edge.curved=.1)

# Network layout
plot(net, layout=layout.random)

layouts <- grep("^layout\\.", ls("package:igraph"), value=TRUE)
layouts <- layouts[c(3,6,8,17)] # pick some layouts to plot
par(mfrow=c(2,2))
for (layout in layouts) {
print(layout)
l <- do.call(layout, list(net))
plot(net, edge.arrow.mode=0, layout=l, main=layout) }
## [1] "layout.circle"
## [1] "layout.fruchterman.reingold"
## [1] "layout.gem"
## [1] "layout.random"

dev.off()
## null device
## 1
# create heat map to represent networks
netm <- get.adjacency(net, attr='weight', sparse=F)
colnames(netm) <- V(net)$media
rownames(netm) <- V(net)$media
palf <- colorRampPalette(c('gold', 'dark orange'))
heatmap(netm[,17:1], Rowv = NA, Colv = NA, col = palf(100),
scale="none", margins=c(10,10))