Visualizing Social Data
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode

Code

Network Data Examples

library(tidyverse)
## ── Attaching packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.1 ──

## ✔ ggplot2 3.3.5     ✔ purrr   0.3.4
## ✔ tibble  3.1.6     ✔ dplyr   1.0.8
## ✔ tidyr   1.2.0     ✔ stringr 1.4.0
## ✔ readr   2.1.2     ✔ forcats 0.5.1

## ── Conflicts ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ readr::edition_get()   masks testthat::edition_get()
## ✖ dplyr::filter()        masks stats::filter()
## ✖ purrr::is_null()       masks testthat::is_null()
## ✖ dplyr::lag()           masks stats::lag()
## ✖ readr::local_edition() masks testthat::local_edition()
## ✖ dplyr::matches()       masks tidyr::matches(), testthat::matches()
library(socviz)
## 
## Attaching package: 'socviz'

## The following object is masked from 'package:kjhutils':
## 
##     %nin%
library(ggraph)
library(tidygraph)
## 
## Attaching package: 'tidygraph'

## The following object is masked from 'package:stats':
## 
##     filter

## The following object is masked from 'package:testthat':
## 
##     matches
#remotes::install_github("kjhealy/kjhnet")
library(kjhnet)

Paul Revere

Matrix version

head(revere)
##               person st_andrews_lodge loyal_nine north_caucus long_room_club
## 1         Adams.John                0          0            1              1
## 2       Adams.Samuel                0          0            1              1
## 3           Allen.Dr                0          0            1              0
## 4 Appleton.Nathaniel                0          0            1              0
## 5        Ash.Gilbert                1          0            0              0
## 6    Austin.Benjamin                0          0            0              0
##   tea_party boston_committee london_enemies
## 1         0                0              0
## 2         0                1              1
## 3         0                0              0
## 4         0                1              0
## 5         0                0              0
## 6         0                0              1
tail(revere)
##                person st_andrews_lodge loyal_nine north_caucus long_room_club
## 249  Willis.Nathaniel                0          0            0              0
## 250 Wingfield.William                1          0            0              0
## 251      Winslow.John                0          0            0              1
## 252     Winthrop.John                0          0            1              0
## 253      Wyeth.Joshua                0          0            0              0
## 254      Young.Thomas                0          0            1              0
##     tea_party boston_committee london_enemies
## 249         1                0              0
## 250         0                0              0
## 251         0                0              0
## 252         0                0              1
## 253         1                0              0
## 254         1                1              0
r_p <- as.matrix(revere[,-1]) %*% t(as.matrix(revere[,-1]))
dim(r_p)
## [1] 254 254
r_p[1:6, 1:6]
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    2    2    1    1    0    0
## [2,]    2    4    1    2    0    1
## [3,]    1    1    1    1    0    0
## [4,]    1    2    1    2    0    0
## [5,]    0    0    0    0    1    0
## [6,]    0    1    0    0    0    1
r_g <- t(as.matrix(revere[,-1])) %*% as.matrix(revere[,-1])

dim(r_g)
## [1] 7 7
r_g
##                  st_andrews_lodge loyal_nine north_caucus long_room_club
## st_andrews_lodge               53          2            3              2
## loyal_nine                      2         10            3              0
## north_caucus                    3          3           59              5
## long_room_club                  2          0            5             17
## tea_party                       3          2           13              2
## boston_committee                1          0            9              5
## london_enemies                  3          3           16              5
##                  tea_party boston_committee london_enemies
## st_andrews_lodge         3                1              3
## loyal_nine               2                0              3
## north_caucus            13                9             16
## long_room_club           2                5              5
## tea_party               97                3              8
## boston_committee         3               21             11
## london_enemies           8               11             62

Tidy version

revere_groups
## # A tbl_graph: 7 nodes and 49 edges
## #
## # An undirected multigraph with 1 component
## #
## # Node Data: 7 × 2 (active)
##      id name            
##   <int> <chr>           
## 1     1 st_andrews_lodge
## 2     2 loyal_nine      
## 3     3 north_caucus    
## 4     4 long_room_club  
## 5     5 tea_party       
## 6     6 boston_committee
## # … with 1 more row
## #
## # Edge Data: 49 × 3
##    from    to value
##   <int> <int> <dbl>
## 1     1     1    53
## 2     1     2     2
## 3     1     3     3
## # … with 46 more rows
revere_groups %>%
  ggraph(layout = "kk") +
  geom_edge_link(aes(width = value), color = "gray80") +
  geom_node_label(aes(label = name)) + theme_graph()
revere_persons %>%
  mutate(centrality = centrality_eigen()) %>%
  ggraph(layout = "stress") +
  geom_edge_link0(aes(edge_width = value), color = "gray60") +
  scale_edge_width(range = c(0.02, 2))+
  geom_node_point() +
  geom_node_label(aes(filter = centrality > 0.9, label = name), size = rel(2.5)) + 
  theme_graph()

The Iliad

Degree centrality

il_tidy
## # A tbl_graph: 311 nodes and 292 edges
## #
## # A directed multigraph with 23 components
## #
## # Node Data: 311 × 3 (active)
##      id name            affil
##   <int> <chr>           <chr>
## 1     1 Antilochus      A    
## 2     2 Agenor          T    
## 3     3 Telamonian Ajax A    
## 4     4 Antiphus        T    
## 5     5 Odysseus        A    
## 6     6 Peirous         T    
## # … with 305 more rows
## #
## # Edge Data: 292 × 3
##    from    to act  
##   <int> <int> <chr>
## 1     1    41 kills
## 2     2    42 kills
## 3     3    43 kills
## # … with 289 more rows
il_tidy %>%
  activate(nodes) %>%
  mutate(centrality = centrality_degree()) %>%
  as_tibble() %>%
  ggplot(mapping = aes(x = centrality)) +
  geom_histogram() +
  labs(x = "Count of Victories", y = "Count of Warriors ") +
  theme_minimal() +
  theme(legend.position = "top")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
il_tidy %>%
  activate(nodes) %>%
  mutate(centrality = centrality_degree()) %>%
  as_tibble() %>%
  arrange(desc(centrality)) %>%
  top_n(10, wt = centrality) %>%
  ggplot(mapping = aes(x = centrality,
                       y = reorder(name, centrality),
                       color = affil)) +
  geom_point(size = 3) +
  labs(x = "Centrality", y = NULL, color = "Side") +
  theme_minimal() +
  theme(legend.position = "top")

Graph representation

il_tidy %>%
  activate(nodes) %>%
  ggraph(layout = "fr") +
  geom_edge_link(color = "gray80") +
  geom_node_point(aes(color = affil)) +
  scale_color_manual(values = c("blue", "red"), 
                     labels = c("Athenian", "Trojan")) +
  guides(color = guide_legend(title = "Side")) +
  labs(title = "Violence in The Iliad") +
  theme(plot.title = element_text(size = rel(3)))
label_colors <- c(prismatic::clr_lighten("blue", 0.7),
                  prismatic::clr_lighten("red", 0.7))
il_tidy %>%
  activate(nodes) %>%
  mutate(centrality = centrality_degree(mode = "out")) %>%
  ggraph(layout = "graphopt") +
  geom_edge_link(aes(start_cap = label_rect(node1.name),
                     end_cap = label_rect(node2.name)),
                 arrow = arrow(length = unit(1.5, 'mm'))) +
  geom_node_point(aes(color = affil)) +
  scale_color_manual(values = c("blue", "red"),
                     labels = c("Athenian", "Trojan")) +
  guides(color = "none", fill = "none") +
  geom_node_label(aes(filter = centrality > 0,
                      label = name, fill = affil),
                      size = rel(2.5)) +
  scale_fill_manual(values = label_colors) +
  labs(title = "Violence in The Iliad") +
  theme_graph() +
  theme(plot.title = element_text(size = rel(3)))

Betweenness centrality

il_tidy %>%
  activate(nodes) %>%
  mutate(centrality = centrality_degree(),
         betweenness = centrality_betweenness()) %>%
  as_tibble() %>%
  arrange(desc(betweenness)) %>%
  top_n(10, wt = betweenness) %>%
  ggplot(mapping = aes(x = betweenness,
                       y = reorder(name,
                       betweenness), color = affil)) +
  geom_point(size = 3) +
  labs(x = "Betweenness", y = NULL, color = "Side") +
  theme_minimal() +
  theme(legend.position = "top")
## Warning in betweenness(graph = graph, v = V(graph), directed = directed, :
## 'nobigint' is deprecated since igraph 1.3 and will be removed in igraph 1.4

Alpha centrality

il_tidy %>%
  activate(edges) %>%
  filter(act == "kills") %>%
  reroute(from = to, to = from) %>%
  activate(nodes) %>%
  mutate(alpha = centrality_alpha()) %>%
  as_tibble() %>%
arrange(desc(alpha)) %>%
    top_n(10, wt = alpha) %>%
  ggplot(mapping = aes(x = alpha,
                       y = reorder(name, alpha),
                       color = affil)) +
  geom_point(size = 3) +
  labs(x = "Alpha Centrality", y = NULL, color = "Side") +
  theme_minimal() +
  theme(legend.position = "top")