Demo 1: Network Data and Visualization

SIOP 2021 Workshop:

Network Analysis for Teams and Organizations

Data taken from: Casciaro, Tiziana, Vincent Dessain, and Elena Corsi. “Moët Hennessy España.” Harvard Business School Case 408-108, February 2008.

Load packages for network analysis

# Setup the igraph package for network analysis and plotting
# Check if igraph is installed. If not - installs the package automatically
if (!"igraph" %in% installed.packages()) install.packages("igraph")
# Load the igraph package, so that we can use functions from it for network analysis
library(igraph)
## 
## Attaching package: 'igraph'
## The following objects are masked from 'package:stats':
## 
##     decompose, spectrum
## The following object is masked from 'package:base':
## 
##     union

Setup Network Data

# Pull network data from the web, in the form of adjacency matrices for each type of tie
energizingMatrix <- as.matrix(read.csv("https://sites.northwestern.edu/nearfutureofwork2021/files/2021/04/Energizing.csv",header=F))
# Pull node attributes from the web
node_att <- read.csv("https://sites.northwestern.edu/nearfutureofwork2021/files/2021/04/Moet_NodeAttributes.csv")
# Create a network object in R
energizingNetwork <- graph_from_adjacency_matrix(energizingMatrix)
# Store the department of each node (vertex)
V(energizingNetwork)$department <- node_att$Department
# Generate colors for each department that employees are in
colbar = rainbow(4) # Select 4 colors
V(energizingNetwork)$color <- colbar[as.factor(V(energizingNetwork)$department)]
# Generate a common layout to use in all plots
myLayout <- layout_with_fr(energizingNetwork)

Individual Level Metrics:

Compare nodes based on Indegree

par(mar=c(0,0,0,0))
# Compare nodes based on indegree
inDegree<-degree(energizingNetwork,mode="in")
sort(inDegree,decreasing=TRUE)[1:5]
## V11 V29 V35 V13 V15 
##   7   6   6   5   5
plot(
  energizingNetwork,vertex.label = NA, vertex.size = inDegree+5,
  edge.arrow.size = 0.5, vertex.color = V(energizingNetwork)$color, layout = myLayout
)

Compare nodes based on Outdegree

par(mar=c(0,0,0,0))
outDegree<-degree(energizingNetwork,mode="out")
sort(outDegree,decreasing=TRUE)[1:5]
## V13  V9 V20 V34 V12 
##  11   7   7   7   6
plot(
  energizingNetwork,vertex.label = NA, vertex.size = outDegree+5,
  edge.arrow.size = 0.5, vertex.color = V(energizingNetwork)$color, layout = myLayout
)

Compare nodes based on Closeness Centrality

par(mar=c(0,0,0,0))
# Out-closeness (using ties leaving the node)
closenessScore<-closeness(energizingNetwork, mode = "out", normalized=T)
## Warning in closeness(energizingNetwork, mode = "out", normalized = T): At
## centrality.c:2784 :closeness centrality is not well-defined for disconnected
## graphs
sort(closenessScore,decreasing=TRUE)[1:5]
##         V8        V34        V28        V19        V13 
## 0.07789474 0.07129094 0.07061069 0.06915888 0.06877323
plot(
  energizingNetwork,vertex.label = NA, vertex.size = closenessScore*150,
  edge.arrow.size = 0.5, vertex.color = V(energizingNetwork)$color, layout = myLayout
)

# In-closeness (using ties heading towards the node)
closenessScore<-closeness(energizingNetwork, mode = "in", normalized=T)
## Warning in closeness(energizingNetwork, mode = "in", normalized = T): At
## centrality.c:2784 :closeness centrality is not well-defined for disconnected
## graphs
sort(closenessScore,decreasing=TRUE)[1:5]
##        V11        V31        V21         V4        V24 
## 0.05873016 0.05323741 0.05089409 0.05068493 0.04868421
plot(
  energizingNetwork,vertex.label = NA, vertex.size = closenessScore*200,
  edge.arrow.size = 0.5, vertex.color = V(energizingNetwork)$color, layout = myLayout
)

Compare nodes based on Betweenness Centrality

par(mar=c(0,0,0,0))
# Compare nodes based on betweenness centrality
betweennessScore<-betweenness(energizingNetwork,directed=TRUE)
sort(betweennessScore,decreasing=TRUE)[1:5]
##       V13       V29       V15       V20       V12 
## 129.33333 126.88333  66.76667  65.88333  65.40000
plot(
  energizingNetwork,vertex.label = NA, vertex.size = sqrt(betweennessScore)/2+5,
  edge.arrow.size = 0.5, vertex.color = V(energizingNetwork)$color, layout = myLayout
)

Compare nodes based on Eigenvector Centrality

par(mar=c(0,0,0,0))
# Compare nodes based on eigenvector centrality
eigenvectorScore <- eigen_centrality(energizingNetwork,directed=TRUE)$vector
sort(eigenvectorScore,decreasing=TRUE)[1:5]
##       V10       V16       V15       V17       V20 
## 1.0000000 0.9478050 0.8769784 0.8326514 0.7336451
plot(
  energizingNetwork,vertex.label = NA, vertex.size = eigenvectorScore*7+4,
  edge.arrow.size = 0.5, vertex.color = V(energizingNetwork)$color, layout = myLayout
)

Team and Organizational Metrics

Network Density

# Overall density
graph.density(energizingNetwork)
## [1] 0.06116643

E-I Index (Internal Density vs. External Range)

# E-I Index (External and Internal Range)
# Compute using the isnar package
if (!"isnar" %in% installed.packages()) devtools::install_github("mbojan/isnar")
# Compute E-I index for the whole network
eiIndex <- isnar::ei(energizingNetwork,"department")

Global Clustering Coefficient

# Global clustering coefficient
transitivity(energizingNetwork) # Look at proportion of connected triads
## [1] 0.2163462
# Average clustering coefficient
transitivity(energizingNetwork,type="average") # Calculate for each node, then average
## [1] 0.2717949

Examine clustering of nodes in the network

par(mar=c(0,0,0,0))
# Examine clustering in the network
#see the number of clusters in the graph and their size
cluster<-cluster_walktrap(energizingNetwork) # there are other algorithms for this, but in your network this might be the most robust
#You can find the number of clusters with 
membership(cluster)   # affiliation list
##  V1  V2  V3  V4  V5  V6  V7  V8  V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 
##   6   3   3   3   7   2   5   2   4   5   2   5   1   4   5   5   5   4   8   5 
## V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 
##   1   4   1   4   9  10   1   1   4   1   1   2   1   1   1   1   2  11
length(sizes(cluster)) #number of clusters
## [1] 11
#and the size the each cluster with 
sizes(cluster) ## note that communities with one node are isolates, or have only a single tie
## Community sizes
##  1  2  3  4  5  6  7  8  9 10 11 
## 11  5  3  6  7  1  1  1  1  1  1
# Visualize clusters - this puts colored circles around the nodes in a community
plot(
cluster, energizingNetwork, col = V(energizingNetwork)$color, layout = myLayout,vertex.label=NA, vertex.size=6,edge.arrow.size=0.5
     )