Bonus Post: Social Network Analysis with the Battles of A Song of Ice and Fire
[This article was first published on Deeply Trivial, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
library(tidyverse) ## Warning: package 'tidyverse' was built under R version 3.4.4 ## -- Attaching packages ----------------------------------------------------------- tidyverse 1.2.1 -- ## v ggplot2 2.2.1 v purrr 0.2.4 ## v tibble 1.4.2 v dplyr 0.7.4 ## v tidyr 0.8.0 v stringr 1.2.0 ## v readr 1.1.1 v forcats 0.2.0 ## Warning: package 'tibble' was built under R version 3.4.4 ## Warning: package 'tidyr' was built under R version 3.4.4 ## Warning: package 'purrr' was built under R version 3.4.4 ## -- Conflicts -------------------------------------------------------------- tidyverse_conflicts() -- ## x dplyr::filter() masks stats::filter() ## x dplyr::lag() masks stats::lag() Battles<-read_csv('https://raw.githubusercontent.com/chrisalbon/war_of_the_five_kings_dataset/master/5kings_battles_v1.csv') ## Parsed with column specification: ## cols( ## .default = col_character(), ## year = col_integer(), ## battle_number = col_integer(), ## major_death = col_integer(), ## major_capture = col_integer(), ## attacker_size = col_integer(), ## defender_size = col_integer(), ## summer = col_integer() ## ) ## See spec(...) for full column specifications.
Next, we'll prepare our data for the network model, which involves extracting the attacker and defender kings, and labeling them as such.
attacker_king<-Battles %>% distinct(attacker_king) %>% rename(label=attacker_king) defender_king<-Battles %>% distinct(defender_king) %>% rename(label=defender_king) nodes<-full_join(attacker_king,defender_king,by="label") nodes<-nodes %>% rowid_to_column("id")
Now we can create the object that will be used to create the figure. We want the figure to contain each of the kings, with lines between them indicating that they battled each other. The thickness of the line will be determined by the number of battles involving those kings.
per_battles<-Battles %>% group_by(attacker_king,defender_king) %>% summarise(weight=n()) %>% ungroup() edges<-per_battles %>% left_join(nodes, by=c("attacker_king" = "label")) %>% rename(from=id) edges<-edges %>% left_join(nodes,by=c("defender_king" = "label")) %>% rename(to=id) edges<-select(edges,from,to,weight)
We have the data we need. Last step is to put it into a table used by the figure, which is created with ggraph.
library(tidygraph) ## Warning: package 'tidygraph' was built under R version 3.4.4 ## ## Attaching package: 'tidygraph' ## The following object is masked from 'package:stats': ## ## filter library(ggraph) ## Warning: package 'ggraph' was built under R version 3.4.4 battles_tidy<-tbl_graph(nodes=nodes, edges=edges, directed=TRUE) battles_tidy %>% activate(edges) %>% arrange(desc(weight)) ## # A tbl_graph: 7 nodes and 14 edges ## # ## # A directed multigraph with 1 component ## # ## # Edge Data: 14 x 3 (active) ## from to weight ## <int> <int> <int> ## 1 1 2 10 ## 2 2 1 9 ## 3 3 2 4 ## 4 3 1 2 ## 5 1 4 2 ## 6 4 1 2 ## # ... with 8 more rows ## # ## # Node Data: 7 x 2 ## id label ## <int> <chr> ## 1 1 Joffrey/Tommen Baratheon ## 2 2 Robb Stark ## 3 3 Balon/Euron Greyjoy ## # ... with 4 more rows ggraph(battles_tidy, layout = "graphopt") + geom_node_point() + geom_edge_link(aes(width = weight), alpha = 0.8) + scale_edge_width(range = c(0.2, 2)) + geom_node_text(aes(label = label), repel = TRUE) + labs(edge_width = "Battles") + theme_graph()