A Study of Social Network Analysis on Hazards Risk Reduction

Keywords: Network analysis, network application, visualization.

Yiwen Wu
2024-08-22

This post introduces one way to visualize networks using the package igraph. It is fairly straightforward, the steps we need to take are:

Essentially, the content in this network project is used to analyze local hazards risk reduction focusing on stakeholders’ collaborative activities and co-worked experience. The network of plans illustrate the extent that existing plan documents are integrated for informed decision making. The network of people demonstrate the types of agency, the frequency of co-working experience, and the depth of conversation in local risk reduction.

Find more information here for the published article if you are interested. Below are step-by-step network visualization.

Attach packages

#install.packages("igraph")
#install.packages("igraphdata")
library(igraph)
#library(igraphdata)
library(dplyr)
library(tidyr)
library(tidyverse)
#install.packages(stringr)
library(ITNr)
library(igraphdata)
library(RColorBrewer)

Import edges and nodes

You may find examples of edges and nodes in txt format in source file.

edges <- read.csv("link.csv")
nodes <- read.csv("node.csv")
# Check the number of nodes
nrow(nodes); length(unique(nodes$id))
[1] 18
[1] 18
# Check the number of unique edges
nrow(edges); nrow(unique(edges[,c("from", "to")]))
[1] 136
[1] 126
# We will collapse all links of the same type between the same two nodes by summing their weights, using aggregate() by “from”, “to”, & “type”
links <- aggregate(edges[,3], edges[,-3], sum)
links <- links[order(links$from, links$to),]
colnames(links)[4] <- "weight"
rownames(links) <- NULL
net <- graph_from_data_frame(d=links, vertices=nodes, directed=F)
# If you have extra attributes in your edge and vertices as appeared in your data collection, 
#you may add them to the edge and vertices. Four instance, the vertex here shows the stakeholders' agency names. 
#The type of the edge also represents the type of meeting that get stakeholders connected. 

E(net)$type
  [1] "lup" "rec" "mit" "rec" "mit" "rec" "mit" "res" "mit" "res"
 [11] "mit" "mit" "lup" "mit" "mit" "mit" "mit" "res" "res" "res"
 [21] "res" "res" "res" "lup" "rec" "rec" "mit" "rec" "mit" "mit"
 [31] "mit" "mit" "mit" "mit" "mit" "mit" "mit" "mit" "mit" "mit"
 [41] "mit" "mit" "mit" "mit" "res" "mit" "res" "mit" "mit" "mit"
 [51] "mit" "mit" "mit" "res" "res" "res" "res" "res" "res" "res"
 [61] "res" "mit" "mit" "mit" "mit" "mit" "mit" "res" "res" "res"
 [71] "res" "res" "res" "mit" "mit" "mit" "mit" "mit" "mit" "mit"
 [81] "mit" "mit" "mit" "mit" "mit" "mit" "mit" "mit" "res" "res"
 [91] "res" "res" "res" "res" "res" "res" "res" "res" "res" "res"
[101] "res" "res" "res" "res" "res" "res" "res" "res" "res" "res"
[111] "res" "res" "res" "res" "res" "res" "res" "res" "res" "res"
[121] "res" "res" "res" "res" "res" "res" "res" "res" "res" "res"
[131] "res" "res" "res" "res" "res" "res"
V(net)$agency #vertex attribute "agency name"
 [1] "CoPlanning"    "CoLegislative" "CoBudget"      "CoPublicWork" 
 [5] "CoEM"          "StateEM"       "CoStormwater"  "CoExecutive"  
 [9] "CoInfo"        "CoBuilding"    "Insurance"     "DisasterSpec" 
[13] "HigherEdu"     "NOAA"          "USACE"         "StateResource"
[17] "DisasterSpec2" "Consultant1"  
#find specific nodes 
V(net)[agency == "CoPlanning"]
+ 1/18 vertex, named, from 438c3e6:
[1] s01
#specific planning type
E(net)[type =="lup"]
+ 3/136 edges from 438c3e6 (vertex names):
[1] s01--s02 s01--s10 s02--s10
# Scale the layout by 5 to increase distance between nodes
layout <- layout_with_fr(net) * 5  

plot(net, 
     layout = layout,
     edge.color="grey",
     vertex.color="orange", 
     vertex.frame.color="#ffffff",
     vertex.label.cex=.6,
     vertex.label=V(net)$agency,
     vertex.label.color="black")

# This plot is to visualize actors based on type (e.g., county, state, fed, private, nonprofit, private)
# set attributes is to add them to the igraph object
# Generate colors based on agency type:
colrs <- c("antiquewhite2", "grey", "gold", "coral","aquamarine")

V(net)$color <- colrs[V(net)$agency.type]
E(net)$color <- as.factor(links$type)
# Compute node degrees (#links) and use that to set node size:
deg <- degree(net, mode="all")
V(net)$size <- deg*3

# use the influence weight for nodes:
V(net)$size <- V(net)$influence*2.2

# Setting them to NA will render no labels:
V(net)$label <- NA

# Set edge width based on weight:
E(net)$width <- E(net)$weight
#change arrow size and edge color:
#E(net)$arrow.size <- .2
E(net)$edge.color <- "azure4"
E(net)$width <- 1+E(net)$weight*.8

# Scale the layout to increase edge length
layout <- layout_with_fr(net)
scaled_layout <- layout * 2  

plot(net,
     vertex.frame.color="#ffffff",
     vertex.label.cex=.6, 
     vertex.label=V(net)$agency,
     vertex.label.color="black",
     layout = scaled_layout)

# Adjustment to the legend
legend("right", c("Local Agency","State Agency", "Federal Agency", "Private Sector", "Nonprofit"), pch=21,
       col="#777777", pt.bg=colrs, pt.cex=2, cex=.8, bty="n", ncol=1)

# Calculate the degree for each node
deg_1 <- degree(net)
head(deg_1)
s01 s02 s03 s04 s05 s06 
 31   2   3  13  13  26 
# Calculate the closeness centrality for each node
clo_1 <- closeness(net, vids = V(net), normalized = F)
head(clo_1)
       s01        s02        s03        s04        s05        s06 
0.05555556 0.03125000 0.03225806 0.04347826 0.04166667 0.05263158 
# Calculate the betweenness centrality for each node
bet_1 <- betweenness(net, normalized = F)
head(bet_1)
      s01       s02       s03       s04       s05       s06 
27.300000  0.000000  0.000000  3.041667  1.850000  9.241667