Research Question

  1. Do the actors with high in-degree centrality also tend to have high out-degree centrality?

  2. Which actors serve as transmitters, transceivers and transcenders in the NGSS tweets network?

Loading Libraries and Data

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.0     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.1     ✔ tibble    3.1.8
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(igraph)
## Warning: package 'igraph' was built under R version 4.2.3
## 
## Attaching package: 'igraph'
## 
## The following objects are masked from 'package:lubridate':
## 
##     %--%, union
## 
## The following objects are masked from 'package:dplyr':
## 
##     as_data_frame, groups, union
## 
## The following objects are masked from 'package:purrr':
## 
##     compose, simplify
## 
## The following object is masked from 'package:tidyr':
## 
##     crossing
## 
## The following object is masked from 'package:tibble':
## 
##     as_data_frame
## 
## The following objects are masked from 'package:stats':
## 
##     decompose, spectrum
## 
## The following object is masked from 'package:base':
## 
##     union
library(tidygraph)
## Warning: package 'tidygraph' was built under R version 4.2.3
## 
## Attaching package: 'tidygraph'
## 
## The following object is masked from 'package:igraph':
## 
##     groups
## 
## The following object is masked from 'package:stats':
## 
##     filter
library(ggraph)
## Warning: package 'ggraph' was built under R version 4.2.3
library(skimr)
## Warning: package 'skimr' was built under R version 4.2.3
library(dplyr)
library(readxl)
library(tidytext)
library(dplyr)
ngss_tweets <- read_xlsx("ngss_tweets.xlsx")

ngss_tweets
## # A tibble: 402 × 91
##    user_id      statu…¹ created_at          scree…² text  source displ…³ reply…⁴
##    <chr>        <chr>   <dttm>              <chr>   <chr> <chr>    <dbl> <chr>  
##  1 316633205    136571… 2021-02-27 17:33:27 loyr26… "Swi… Twitt…     117 <NA>   
##  2 316633205    136321… 2021-02-20 20:02:37 loyr26… "Was… Twitt…     200 <NA>   
##  3 13391550230… 136570… 2021-02-27 17:04:18 Ngss_18 "Ras… Twitt…      34 <NA>   
##  4 13391550230… 136529… 2021-02-26 13:51:35 Ngss_18 "Kan… Twitt…      28 <NA>   
##  5 13391550230… 136565… 2021-02-27 13:44:20 Ngss_18 "Seb… Twitt…      44 <NA>   
##  6 13391550230… 136529… 2021-02-26 13:45:00 Ngss_18 "Bin… Twitt…      71 <NA>   
##  7 13391550230… 136549… 2021-02-27 02:52:34 Ngss_18 "Buk… Twitt…     194 <NA>   
##  8 426610914    136570… 2021-02-27 17:03:23 Furlow… "@IB… Twitt…     280 136568…
##  9 426610914    136567… 2021-02-27 14:41:01 Furlow… "@IB… Twitt…      35 136546…
## 10 1449382200   136566… 2021-02-27 14:17:34 TdiShe… "I a… Twitt…     234 <NA>   
## # … with 392 more rows, 83 more variables: reply_to_user_id <chr>,
## #   reply_to_screen_name <chr>, is_quote <lgl>, is_retweet <lgl>,
## #   favorite_count <dbl>, retweet_count <dbl>, quote_count <lgl>,
## #   reply_count <lgl>, hashtags <lgl>, symbols <lgl>, urls_url <lgl>,
## #   urls_t.co <lgl>, urls_expanded_url <lgl>, media_url <lgl>,
## #   media_t.co <lgl>, media_expanded_url <lgl>, media_type <lgl>,
## #   ext_media_url <lgl>, ext_media_t.co <lgl>, ext_media_expanded_url <lgl>, …

Creating Edgelist

ties_1 <- ngss_tweets |>
  relocate(sender = screen_name,
           target = reply_to_screen_name) |>
  select(sender,
         target,
         created_at,
         text) 

ties_1
## # A tibble: 402 × 4
##    sender       target      created_at          text                            
##    <chr>        <chr>       <dttm>              <chr>                           
##  1 loyr2662     <NA>        2021-02-27 17:33:27 "Switching gears for a bit for …
##  2 loyr2662     <NA>        2021-02-20 20:02:37 "Was just introduced to the Eng…
##  3 Ngss_18      <NA>        2021-02-27 17:04:18 "Rasanya pengen banget punya te…
##  4 Ngss_18      <NA>        2021-02-26 13:51:35 "Kangen mantan boleh gak sih\U0…
##  5 Ngss_18      <NA>        2021-02-27 13:44:20 "Sebenarnya udah pengen ngejauh…
##  6 Ngss_18      <NA>        2021-02-26 13:45:00 "Bingung mau cerita kesiapa;) t…
##  7 Ngss_18      <NA>        2021-02-27 02:52:34 "Bukannya gak boleh liat keatas…
##  8 Furlow_teach IBchemmilam 2021-02-27 17:03:23 "@IBchemmilam @chemmastercorey …
##  9 Furlow_teach IBchemmilam 2021-02-27 14:41:01 "@IBchemmilam @chemmastercorey …
## 10 TdiShelton   <NA>        2021-02-27 14:17:34 "I am so honored and appreciati…
## # … with 392 more rows

Unnesting Usernames and Dropping Na Values

ties<- ties_1 |>
  unnest_tokens(input = target,
                output = receiver,
                to_lower = FALSE) |>
  relocate(sender, receiver) |>
  drop_na()
  

ties
## # A tibble: 119 × 4
##    sender          receiver        created_at          text                     
##    <chr>           <chr>           <dttm>              <chr>                    
##  1 Furlow_teach    IBchemmilam     2021-02-27 17:03:23 "@IBchemmilam @chemmaste…
##  2 Furlow_teach    IBchemmilam     2021-02-27 14:41:01 "@IBchemmilam @chemmaste…
##  3 jeansciqueen    jeansciqueen    2021-02-27 15:30:46 "Wanda, any book you can…
##  4 haruzoee        JAPANFESS       2021-02-27 14:49:31 "@JAPANFESS manga masih …
##  5 betsylawrence82 KATSorg         2021-02-27 14:10:36 "@KATSorg is seeking pre…
##  6 Joelwry_dev     ngss_official   2021-02-27 14:07:06 "@ngss_official Loved d …
##  7 richbacolor     richbacolor     2021-02-27 12:50:58 "The #ngss vans are gonn…
##  8 masamasa_ngss   EoMTcwAOjlyfS05 2021-02-23 16:30:22 "@EoMTcwAOjlyfS05 肝炎の…
##  9 masamasa_ngss   uy_amm          2021-02-21 23:15:50 "@uy_amm 国印?"         
## 10 masamasa_ngss   RuiRui19995101  2021-02-27 05:54:21 "@RuiRui19995101 やろ"   
## # … with 109 more rows
write_csv(ties,"ngss-edgelist.csv")

Creating Node List

actors_1 <- ties |>
  select(sender, receiver) |>
  pivot_longer(cols = c(sender,receiver))

actors_1
## # A tibble: 238 × 2
##    name     value          
##    <chr>    <chr>          
##  1 sender   Furlow_teach   
##  2 receiver IBchemmilam    
##  3 sender   Furlow_teach   
##  4 receiver IBchemmilam    
##  5 sender   jeansciqueen   
##  6 receiver jeansciqueen   
##  7 sender   haruzoee       
##  8 receiver JAPANFESS      
##  9 sender   betsylawrence82
## 10 receiver KATSorg        
## # … with 228 more rows
actors <- actors_1 |>
  select(value) |>
  rename(actors = value) |> 
  distinct()

actors
## # A tibble: 132 × 1
##    actors         
##    <chr>          
##  1 Furlow_teach   
##  2 IBchemmilam    
##  3 jeansciqueen   
##  4 haruzoee       
##  5 JAPANFESS      
##  6 betsylawrence82
##  7 KATSorg        
##  8 Joelwry_dev    
##  9 ngss_official  
## 10 richbacolor    
## # … with 122 more rows

There are 132 unique actors in the network.

Creating a Network Graph

ngss_network <- tbl_graph(edges = ties, 
                          nodes = actors, 
                          directed = TRUE)
ngss_network
## # A tbl_graph: 132 nodes and 119 edges
## #
## # A directed multigraph with 60 components
## #
## # Node Data: 132 × 1 (active)
##   actors         
##   <chr>          
## 1 Furlow_teach   
## 2 IBchemmilam    
## 3 jeansciqueen   
## 4 haruzoee       
## 5 JAPANFESS      
## 6 betsylawrence82
## # … with 126 more rows
## #
## # Edge Data: 119 × 4
##    from    to created_at          text                                          
##   <int> <int> <dttm>              <chr>                                         
## 1     1     2 2021-02-27 17:03:23 @IBchemmilam @chemmastercorey I’m familiar w/…
## 2     1     2 2021-02-27 14:41:01 @IBchemmilam @chemmastercorey How well does t…
## 3     3     3 2021-02-27 15:30:46 Wanda, any book you can recommend in science/…
## # … with 116 more rows
autograph(ngss_network)

Measuring Centrality Degree

ngss_network <- ngss_network |>
  activate(nodes) |>
  mutate(in_degree = centrality_degree(mode = "in"),
         out_degree = centrality_degree(mode = "out"))
  as_tibble(ngss_network)
## # A tibble: 132 × 3
##    actors          in_degree out_degree
##    <chr>               <dbl>      <dbl>
##  1 Furlow_teach            0          2
##  2 IBchemmilam             2          0
##  3 jeansciqueen            1          1
##  4 haruzoee                0          1
##  5 JAPANFESS               1          0
##  6 betsylawrence82         0          1
##  7 KATSorg                 1          0
##  8 Joelwry_dev             0          1
##  9 ngss_official           3          1
## 10 richbacolor             1          1
## # … with 122 more rows

Based on the centrality degree measures, it seems as though the users with the highest in-degree measures also tend have the among the highest out-degree, making them transcenders. The top 5 transcenders are:

The top transmitters are:

The top transceivers are:

What’s interesting, particularly for the transmitters and transceivers, is that the top accounts have “NGSS” in the name, signifying that they may play a very specific role in spreading the word and leading conversation about NGSS.

ngss_network |> 
  as_tibble() |>
  skim()
Data summary
Name as_tibble(ngss_network)
Number of rows 132
Number of columns 3
_______________________
Column type frequency:
character 1
numeric 2
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
actors 0 1 4 15 0 132 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
in_degree 0 1 0.9 1.03 0 0 1 1 6 ▇▁▁▁▁
out_degree 0 1 0.9 1.00 0 0 1 1 5 ▇▁▁▁▁

Each actor had an average of 2.09 alters.

Visualizations

In-Degree Histogram

ngss_network |> 
  as_tibble() |>
  ggplot() +
  geom_histogram(aes(x = in_degree), color = "pink", fill = "pink") +
  labs(title = "Actor In-Degree Measures")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Based on in-degree, no one received more than 6 replies, a little over 60 actors received at least one reply, around 50 recieved no replies at all and just under 10 received between 2 to 3 replies.

Out-Degree Histogram

ngss_network |> 
  as_tibble() |>
  ggplot() +
  geom_histogram(aes(x = out_degree), color = "orange", fill = "orange") +
  labs(title = "Actor Out-Degree Measures")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Based on out-degree, no one replied to more than 5 tweets, a little of 50 actors replied at least once, around 50 didn’t reply at all and just under 10 had sent at least two to 3 replies.

Betweeness and Closeness Measures

ngss_network <-ngss_network |>
  activate(nodes) |>
  mutate(betweenness = centrality_betweenness(), closeness = centrality_closeness())

ngss_network |>
  as_tibble()
## # A tibble: 132 × 5
##    actors          in_degree out_degree betweenness closeness
##    <chr>               <dbl>      <dbl>       <dbl>     <dbl>
##  1 Furlow_teach            0          2           0     1    
##  2 IBchemmilam             2          0           0   NaN    
##  3 jeansciqueen            1          1           0   NaN    
##  4 haruzoee                0          1           0     1    
##  5 JAPANFESS               1          0           0   NaN    
##  6 betsylawrence82         0          1           0     1    
##  7 KATSorg                 1          0           0   NaN    
##  8 Joelwry_dev             0          1           0     0.333
##  9 ngss_official           3          1           3     1    
## 10 richbacolor             1          1           0   NaN    
## # … with 122 more rows

NGSS_tweeps and ms_hyphenated have the highest betweeness scores, at 22 and 6, respectively. The two play the biggest roles in connecting the network. Giving that ‘NGSS’ is in the NGSS_tweeps name, it is clear that this account is doing a lot of bridging between the actors.

In terms of closeness, many of the actors had a closeness between .5 and 1, which signifying very close proximity between each of the actors.

Sociograms

Out-Degree Sociogram

ggraph(ngss_network, layout = "kk") + 
  geom_node_point(aes(color = out_degree, size = 3)) +
  geom_node_text(aes(label = actors, size = out_degree/2),
                 repel=TRUE) +
  geom_edge_arc(arrow = arrow(length = unit(0.5, 'mm')), 
                 end_cap = circle(1, 'mm'),
                 alpha = .2, size = 0.1) +
  scale_color_gradient(low = "lightpink", high = "deeppink") +
  labs(title = "#NGSS Tweets Sociogram Based on Out-Degree") +
  theme_graph()
## Warning in geom_edge_arc(arrow = arrow(length = unit(0.5, "mm")), end_cap =
## circle(1, : Ignoring unknown parameters: `edge_size`
## Warning: Using the `size` aesthetic in this geom was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` in the `default_aes` field and elsewhere instead.
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## not found in Windows font database

## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_stringMetric, as.graphicsAnnot(x$label)): font family
## not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning: ggrepel: 4 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

In-Degree Sociogram

ggraph(ngss_network, layout = "kk") + 
  geom_node_point(aes(color = in_degree, size = 3)) +
  geom_node_text(aes(label = actors, size = in_degree/2),
                 repel=TRUE) +
  geom_edge_arc(arrow = arrow(length = unit(0.5, 'mm')), 
                 end_cap = circle(1, 'mm'),
                 alpha = .2, size = 0.1) +
  scale_color_gradient(low = "lightblue", high = "darkblue") +
  labs(title = "#NGSS Tweets Sociogram Based on In-Degree") +
  theme_graph()
## Warning in geom_edge_arc(arrow = arrow(length = unit(0.5, "mm")), end_cap =
## circle(1, : Ignoring unknown parameters: `edge_size`
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning: ggrepel: 3 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database

Key Findings, Final Implications and Future Studies