##1 network objects: importing, exploring, and manipulating network data ########################################################### ##1.1 Starting from scratch ##First, in Statnet: library(statnet) #Adding Edges g <- network.initialize(5) # Create an empty graph g[1,2] <- 1 # Add an edge from 1 to 2 g[2,] <- 1 # Add edges from 2 to everyone else g # Examine the result m <- matrix(0, nrow=5, ncol=5) # Create an adjacency matrix m[3,4:5] <- 1 # Add entries from 3 to 4 and 5 g[m>0] <- 1 # Add more entries g #Delete edges g[3,5] <- 0 # Remove the edge from 3 to 5 g # Its gone! g[,] <- 0 # Remove all edges g # Now, an empty graph ##Now, in igraph library(igraph) # The function make_graph() can work two ways: # 1. as a vector of an even number of node IDs where each pair of adjacent nodes is considered an edge # illustrated here with spacing make_graph( c(1,2, 2,3, 3,4), directed=FALSE) #or 2. using a symbolic formula # `-` undirected tie # `--+` directed tie (`+` is arrow's head) # `:` refer to node sets (e.g. `A -- B:C` creates ties `A -- B` and `A -- C`) # A network is either directed or undirected, it is not possible mix directed and undirected ties g1 <- make_graph(~ A - B, B - C:D:E) g2 <- make_graph(~ A --+ B, B +-- C, A --+ D:E, B --+ A) g2 #To interpret the printout: #First line includes # - Class of the object (`IGRAPH`) # - An ID of the object, not of particular interest (see also `?igraph::graph_id`) # A set of four slots for letter codes indicating, in order: # `U` or `D` if the network is `U`ndirected or `D`irected # `N` if the nodes have names # `W` if the network is weighted # `B` if the network is bipartite # Number of nodes # Number of edges # Starting with `+ attr:` list of present attributes, each of the form `nameoftheattribute (x/y)` where # `x` informs about the type of an attribute: `v`ertex, `e`dge or `g`raph attribute # `y` informs about the mode of an attribute: `n`umeric, `c`haracter, `l`ogical, or e`x`tended (e.g. lists) # Starting with `+ edges:` a list of (some of) the edges of the network ########################################### ##2.2 Importing Relational Data #Be sure to be in the directory where you stored the data for the workshop. If you've not set the working directory, you must do so now. See Section 1.7 for how to do this. #You can use setwd() to change it, or platform specific shortcuts getwd() # Check what directory you're in list.files() # Check what's in the working directory #Read an adjacency matrix (R stores it as a data frame by default) relations <- read.csv("relationalData.csv",header=FALSE,stringsAsFactors=FALSE) relations #Here's a case where matrix format is preferred relations <- as.matrix(relations) # convert to matrix format #Read in some vertex attribute data (okay to leave it as a data frame) nodeInfo <- read.csv("vertexAttributes.csv",header=TRUE) nodeInfo #Since our relational data has no row/column names, let's set them now rownames(relations) <- nodeInfo$name colnames(relations) <- nodeInfo$name relations #For more information. . . ?list.files ?read.csv ?as.matrix ?rownames ########################################################### ##2.3 Creating network objects #throws an error if relations isn't a network! nrelations<-network(as.matrix(relations),directed=FALSE) # Create a network object based on relations nrelations # Get a quick description of the data #now in igraph: library(igraph) irelations<-graph_from_adjacency_matrix(as.matrix(relations),mode="directed") #For more information. . . ?network ?as.network.matrix ########################################################### ##2.4 Description and Visualization summary(irelations) #summary ecount(irelations) #How many edges vcount(irelations) #How many vertices plot(irelations, layout=layout_with_fr, vertex.color="red", vertex.size=15, edge.arrow.size=0.5, vertex.label.color="black") detach("package:igraph") summary(nrelations) # Get an overall summary network.dyadcount(nrelations) # How many dyads in nflo? network.edgecount(nrelations) # How many edges are present? network.size(nrelations) # How large is the network? as.sociomatrix(nrelations) # Show it as a sociomatrix nrelations[,] # Another way to do it plot(nrelations,displaylabels=T) # Plot with names plot(nrelations,displaylabels=T,mode="circle") # A less useful layout... library(sna) # Load the sna library gplot(nrelations) # Requires sna gplot(relations) # gplot Will work with a matrix object too #For more information. . . ?summary.network ?network.dyadcount ?network.edgecount ?as.sociomatrix ?as.matrix.network ?is.directed ########################################################### ##2.5 Network and Vertex Attributes #Add some attributes nrelations %v% "id" <- nodeInfo$id # Add in our vertex attributes nrelations %v% "age" <- nodeInfo$age nrelations %v% "sex" <- nodeInfo$sex nrelations %v% "handed" <- nodeInfo$handed nrelations %v% "lastDocVisit" <- nodeInfo$lastDocVisit #Listing attributes list.vertex.attributes(nrelations) # List all vertex attributes list.network.attributes(nrelations) # List all network attributes #Retrieving attributes nrelations %v% "age" # Retrieve vertex ages nrelations %v% "id" # Retrieve vertex ids #For more information. . . ?attribute.methods #################################### #2.6 Edgelists edgelist<-read.csv("edgeList.csv") edgeNet<-network(edgelist,matrix.type="edgelist") edgeNet plot(edgeNet,displaylabels=T) #what's missing? plot(edgeNet,displaylabels=T,edge.lwd=edgeNet%e%"Weight"*10) ##how can you extract the weights? edgeNet[,] edgeNet%e%"Weight" as.sociomatrix.sna(edgeNet,"Weight") as.edgelist.sna(edgeNet) ##now in igraph library(igraph) #this will throw an error - why? iedge<-graph_from_edgelist(edgelist,directed=T) iedge<-graph_from_data_frame(edgelist,directed=T) plot(iedge) #where are the weights? E(iedge)$Weight plot(iedge,edge.width=E(iedge)$Weight*5) detach("package:igraph") ########################################################### ########################################################### ##2 Classical Network Analysis with the SNA package ##2.1 Getting started library(sna) # Load the sna library library(help="sna") # See a list of help pages for sna package load("introToSNAinR.Rdata") # Load supplemental workshop data - note this name has changed from the video! ########################################################### ##2.2 Network visualization with gplot() #Plotting the data we imported earlier gplot(nrelations) gplot(nrelations,displaylabels=TRUE) # This time with labels #Let's color the nodes in sex-stereotypic colors nodeColors<-ifelse(nodeInfo$sex=="F","hotpink","dodgerblue") gplot(relations,gmode="graph",displaylabels=TRUE,vertex.col=nodeColors) #Using data we just loaded in, plot the contiguity among nations in 1993 (from the Correlates of War (CoW)1 project) gplot(contig_1993) # The default visualization gplot(contig_1993, usearrows=FALSE) # Turn off arrows manually gplot(contig_1993, gmode="graph") # Can also tell gplot the data is undirected #We can add labels to the vertices gplot(contig_1993, gmode="graph",displaylabels=TRUE,label.cex=0.5,label.col="blue") #Other ways to specify the labeling gplot(contig_1993,gmode="graph",label=network.vertex.names(contig_1993),label.cex=0.5,label.col="blue") #Here's an example of directed data|militarized interstate disputes (MIDs) for 1993 gplot(mids_1993,label.cex=0.5,label.col="blue",displaylabels=TRUE) #All those isolates can get in the way|we can suppress them using displayisolates gplot(mids_1993,label.cex=0.5,label.col="blue",displaylabels=TRUE,displayisolates=FALSE) #The default layout algorithm is that of Frutchterman-Reingold (1991), can use others gplot(mids_1993,label.cex=0.5,label.col="blue",displaylabels=TRUE,displayisolates=FALSE,mode="circle") # The infamous circle #or perhaps gplot(mids_1993,label.cex=0.5,label.col="blue",displaylabels=TRUE,displayisolates=FALSE,mode="mds") # MDS of position similarity #or perhaps gplot(mids_1993,label.cex=0.5,label.col="blue",displaylabels=TRUE,displayisolates=FALSE,mode="target") # a target #When a layout is generated, the results can be saved for later reuse: coords <- gplot(contig_1993,gmode="graph",label=colnames(contig_1993[,]),label.cex=0.5,label.col="blue") # Capture the magic of the moment coords # Show the vertex coordinates #Saved (or a priori) layouts can be used via the coord argument gplot(mids_1993,gmode="graph",label=colnames(contig_1993[,]),label.cex=0.5,label.col="blue",coord=coords) #When the default settings are insuficient, interactive mode allows for tweaking coords <- gplot(contig_1993, interactive=TRUE) # Modify and save gplot(contig_1993,coord=coords,displaylabels=TRUE,gmode="graph",label.cex=0.5,label.col="blue") # Should reproduce the modified layout #For more information. . . ?gplot ?gplot.layout