Network Analysis

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.4.4     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.0
✔ purrr     1.0.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(igraph)                    # This is the package to analyze the network

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(visNetwork)                # Creates visualizations of the network
library(DT)
library(plotly)

Attaching package: 'plotly'

The following object is masked from 'package:igraph':

    groups

The following object is masked from 'package:ggplot2':

    last_plot

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

    filter

The following object is masked from 'package:graphics':

    layout
library(broom)                     # includes some of our regression functions
friendships <- read_csv("friendships.csv")
Rows: 6972 Columns: 4
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
dbl (4): nominator, nominated, score, expected_score

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
friendship_nodes <- read_csv("friendship_nodes.csv")
Rows: 84 Columns: 2
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
dbl (2): id, name

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
friendships |>
  group_by(nominator) |>
  summarize(Mean = round(mean(score),1)) |>
  arrange(-Mean) |>
  datatable(rownames = F, caption ='Average friendship ratings given by each student' )

This table shows the average friendship score given to classmates by each individual in the class where 0 = does not know the person, 3 = friend, and 5 = one of my best friends.

friendships |>
  group_by(nominated) |>
  summarize(Mean = round(mean(score),1)) |>
  arrange(-Mean) |>
  datatable(rownames = F, caption = 'Average friendship ratings given to each student' )

This table shows the average friendship rating given to each individual by their classmates where 0 = do not know them, 3 = friend, and 5 = one of my best friends.

friendships_model <- lm(expected_score ~ score, data = friendships)

friendships |>
  plot_ly(x = ~score, y = ~expected_score) |>
  add_markers() |>
  add_lines(y = fitted(friendships_model))

This is a graph and regression line of the friendship scores and expected friendship scores among classmates.

amigos <- friendships |>
  filter(score > 2) |>
  select(nominator, nominated) |>
  rename(from = nominator) |>
  rename(to = nominated)
friend_network <- graph_from_data_frame(amigos, friendship_nodes, directed = T)
friendship_nodes |>
  mutate(named_friends = degree((friend_network), mode = "out")) |>
  mutate(named_by_others = degree((friend_network), mode = "in")) |>
  mutate(popularity = named_by_others - named_friends) |>
  select(named_friends, named_by_others, popularity) |>
  datatable(rownames = F)

This is a data table showing how many classmates each individual identified as a friend, how many of their classmates identified them as a friend, and their relative popularity.

friendship_nodes |>
  mutate(named_friends = degree((friend_network), mode = "out")) |>
  mutate(named_by_others = degree((friend_network), mode = "in")) |>
  plot_ly(x = ~named_friends) |>
  add_histogram() |>
  layout(title = "How many friends students named")

This is a histogram showing the number of classmates each individual identified as a friend.

reciprocity(friend_network, mode = "ratio")
[1] 0.527088

This is the friendship reciprocity ratio, indicating that aproximately 53% of friendships named for classmates were reciprocated.

best_friends <- friendships |>
  filter(score > 4) |>
  select(nominator, nominated) |>
  rename(from = nominator) |>
  rename(to = nominated)
bff_network <- graph_from_data_frame(best_friends, friendship_nodes, directed = T)
friendship_nodes |>
  mutate(group = membership(infomap.community(bff_network))) |>
  mutate(value = degree(bff_network)) |>
  visNetwork(best_friends, main = "Network of best friendship") |>
  visIgraphLayout(layout = "layout_nicely") |>
  visEdges(arrows = "to") |>
  visOptions(highlightNearest = T, nodesIdSelection = T)
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `group = membership(infomap.community(bff_network))`.
Caused by warning:
! `infomap.community()` was deprecated in igraph 2.0.0.
ℹ Please use `cluster_infomap()` instead.

This is a network of best friendships for classmates. The size of the nodes are larger based on being identified as a best friend. Communities of best friends are indicated by color.