library(readr)
## Warning: 程辑包'readr'是用R版本4.3.2 来建造的
library(tidyverse)
## Warning: 程辑包'tidyverse'是用R版本4.3.3 来建造的
## Warning: 程辑包'ggplot2'是用R版本4.3.3 来建造的
## Warning: 程辑包'forcats'是用R版本4.3.2 来建造的
## Warning: 程辑包'lubridate'是用R版本4.3.2 来建造的
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.3     ✔ purrr     1.0.2
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.5.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ── 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)
## Warning: 程辑包'igraph'是用R版本4.3.3 来建造的
## 
## 载入程辑包:'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
df = read_csv("C:/Users/tsong/Downloads/Basic_LinkedInDataExport_03-14-2024/Connections.csv", skip = 3, show_col_types = FALSE)
str(df)
## spc_tbl_ [2,420 × 7] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ First Name   : chr [1:2420] "Rémi" "Lynn" "Bianca" "Jay" ...
##  $ Last Name    : chr [1:2420] "Nore" "Mark" "Iacobacci" "Tan, CFA" ...
##  $ URL          : chr [1:2420] "https://www.linkedin.com/in/reminore" "https://www.linkedin.com/in/lynnmark" "https://www.linkedin.com/in/bianca-iacobacci" "https://www.linkedin.com/in/jay-tan-cfa-aa682867" ...
##  $ Email Address: chr [1:2420] NA NA NA NA ...
##  $ Company      : chr [1:2420] "Air France" "McGill University - Desautels Faculty of Management" "MAVRIK CORP." "LionGuard Capital Management Inc." ...
##  $ Position     : chr [1:2420] "Corporate Finance Manager" "Manager, Alumni Programs" "Investment Analyst" "Portfolio Manager" ...
##  $ Connected On : chr [1:2420] "14 Mar 2024" "13 Mar 2024" "13 Mar 2024" "13 Mar 2024" ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   `First Name` = col_character(),
##   ..   `Last Name` = col_character(),
##   ..   URL = col_character(),
##   ..   `Email Address` = col_character(),
##   ..   Company = col_character(),
##   ..   Position = col_character(),
##   ..   `Connected On` = col_character()
##   .. )
##  - attr(*, "problems")=<externalptr>
contacts_by_company <- df %>% group_by(Company) %>% summarise(Count = n()) %>% arrange(desc(Count))

total_contacts = df %>% summarise(Total_Count = n())
print(contacts_by_company)
## # A tibble: 1,646 × 2
##    Company                                             Count
##    <chr>                                               <int>
##  1 <NA>                                                   81
##  2 McGill University - Desautels Faculty of Management    45
##  3 McGill University                                      30
##  4 Desautels Capital Management                           21
##  5 Self-employed                                          19
##  6 Deloitte                                               18
##  7 EDHEC Business School                                  18
##  8 RBC                                                    17
##  9 BNP Paribas                                            16
## 10 EY                                                     14
## # ℹ 1,636 more rows
print(total_contacts)
## # A tibble: 1 × 1
##   Total_Count
##         <int>
## 1        2420
edges <- df %>%
  select(Company, Position, `Connected On`) %>%
  distinct() %>%
  group_by(Company, Position) %>%
  summarise(Count = n_distinct(`Connected On`), .groups = 'drop') %>%
  filter(Count > 1) %>%
  mutate(Position = as.character(Position),
         Position = paste(Company, Position, sep = ": ")) %>%
  select(-Count) %>%
  arrange(Position) %>%
  distinct()

graph = graph_from_data_frame(edges,directed = TRUE)
## Warning in graph_from_data_frame(edges, directed = TRUE): In `d' `NA' elements
## were replaced with string "NA"
plot(graph, edge.arrow.size=0.5, vertex.size =5,vertex.label.dist = 2, vertex.label.cex = 0.8)

# Create a label for nodes (using First Name and 1 letter of Last Name)
df <- df %>%rename(First_Name = "First Name", Last_Name = "Last Name")%>%
  mutate(Label = paste(First_Name, substr(Last_Name, 1, 1), sep = " "))
# Get unique contacts as nodes
nodes <- df %>%
  distinct(Label, Company) %>%
  mutate(ID = row_number())

# Rename columns as needed
nodes <- nodes %>%
  select(ID, Label, Company)

# Print nodes data frame
print(nodes)
## # A tibble: 2,384 × 3
##       ID Label      Company                                            
##    <int> <chr>      <chr>                                              
##  1     1 Rémi N     Air France                                         
##  2     2 Lynn M     McGill University - Desautels Faculty of Management
##  3     3 Bianca I   MAVRIK CORP.                                       
##  4     4 Jay T      LionGuard Capital Management Inc.                  
##  5     5 Weiting Z  Susallwave                                         
##  6     6 Vladimir D Chess Federation of Canada                         
##  7     7 Drishti J  Desautels Capital Management                       
##  8     8 Wei L      Fiera Capital                                      
##  9     9 Emma P     Medisca                                            
## 10    10 Ziyuan W   PwC Canada                                         
## # ℹ 2,374 more rows
edges <-  df %>%
  distinct(Label, Company) %>%
  mutate(ID = row_number())%>%inner_join(nodes, by = c("Company" = "Company"))%>%filter(ID.x != ID.y) %>%
  select(from = ID.x, to = ID.y)%>% distinct()
## Warning in inner_join(., nodes, by = c(Company = "Company")): Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 2 of `x` matches multiple rows in `y`.
## ℹ Row 17 of `y` matches multiple rows in `x`.
## ℹ If a many-to-many relationship is expected, set `relationship =
##   "many-to-many"` to silence this warning.
edges
## # A tibble: 9,826 × 2
##     from    to
##    <int> <int>
##  1     2   126
##  2     2   151
##  3     2   170
##  4     2   179
##  5     2   210
##  6     2   212
##  7     2   218
##  8     2   230
##  9     2   231
## 10     2   242
## # ℹ 9,816 more rows
# Create graph
graph <- graph_from_data_frame(d = edges, vertices = nodes, directed = TRUE)

# Plot the graph
plot(graph, edge.arrow.size = 0.5, vertex.size = 5, vertex.label.dist = 2, vertex.label.cex = 0.8)

myself <- data.frame(ID = max(nodes$ID) + 1, Label = "Myself", Company = "McGill University")
nodes <- bind_rows(nodes, myself)
nodes$color <- ifelse(nodes$Label == "Myself", "red", "green")
nodes$shape <- ifelse(nodes$Label == "Myself", "square", "circle")
nodes$size <- ifelse(nodes$Label == "Myself", 10, 1)
graph <- graph_from_data_frame(d = edges, vertices = nodes, directed = TRUE)

V(graph)$color <-nodes$color 
V(graph)$shape <-nodes$shape
V(graph)$size <-nodes$size
plot(graph, vertex.color=V(graph)$color,vertex.shapes=V(graph)$shape, vertex.size = V(graph)$size, vertex.label.dist = 10,  vertex.label.cex = 0.8,  edge.arrow.size = 0.5)

library(tidygraph)
## Warning: 程辑包'tidygraph'是用R版本4.3.3 来建造的
## 
## 载入程辑包:'tidygraph'
## The following object is masked from 'package:igraph':
## 
##     groups
## The following object is masked from 'package:stats':
## 
##     filter
graph <- tbl_graph(nodes = nodes, edges = edges, directed = FALSE)
library(ggraph)
## Warning: 程辑包'ggraph'是用R版本4.3.3 来建造的
ggraph(graph, layout = "fr") +
  geom_edge_link() +
  geom_node_point(aes(color = color, size = size, shape = shape)) +
  scale_color_identity() +
  scale_size_continuous(range = c(2, 10)) +  
  theme_void()