Explore LinkedIn Connections in R
In this blog I have made an attempt to create a shiny dashboard using connections data downloaded from LinkedIn.
Requirements- Knowledge of shiny, shinydashboard and data cleaning and transformation using dplyr.
The data can be downloaded from LinkedIn using the following steps:
- Go to LinkedIn
- Click on Me and then Click Settings & Privacy
- Go to Data Privacy and Click on How LinkedIn uses your data
- Click on Get a copy of your data
- Select Connections
- Click on Request Archive
- Mention your password
- Request will be processed and a mail will be sent in 10–15 mins
- Click on the Link in the mail and download the zip file
- The zip file contains the file Connections.csv that is used in the dashboard
The code used to create the dashboard is mentioned below. I have made an attempt to add comments in the code so that it is self explanatory.
library(shiny)
library(shinydashboard)
library(tidyverse)# Loading data
# Skipping two rowsdata <- read_csv(“Connections.csv”, skip = 2)# Cleaning names using janitor package
# Modified connected_on for proper format
# Added connected_year columndata <- data %>% janitor::clean_names() %>%
mutate(connected_on = as.Date(connected_on, format = ‘%d %B %Y’)) %>%
mutate(connected_year = format(connected_on, format = ‘%Y’))# Removed email from the data as it will be displayed at the end of the dashboarddataem <- data %>% select(-email_address)# Calculated first date and last date for default values in the date selectorfirstdate <- min(dataem$connected_on)lastdate <- max(dataem$connected_on)# Extracted first name of first connection to be displayed in a boxfirstname <- dataem %>% arrange(connected_on) %>% head(1) %>% select(first_name) %>% pull()# Color for plotsstriptext <- “#99000D”
plotbk <- “lightblue”colr <- “darkorange2”header = dashboardHeader(title = “LinkedIn Connections”, titleWidth = 450)sidebar = dashboardSidebar(
# To disable sidebar
disable = TRUE,
sidebarMenu(
menuItem(“Connections”, tabName = “LinePlot”)
)
)body = dashboardBody(
### Adding the CSS style
tags$head(tags$style(HTML(‘
.main-header .logo {
font-family: “Georgia”, Times, “Times New Roman”, serif;
font-weight: bold;
font-size: 24px;
}
‘))),
# Boxes need to be put in a row (or column)
tabItems(
tabItem(tabName = “LinePlot”,
# Output box with text
fluidRow(
valueBoxOutput(“journey”, width =12)),
# Date selector
fluidRow(
box(width = 6, background = “teal”,
br(), “ “,
dateInput(“start_date”, “Select Start Date”, value = firstdate,
min = “2001–01–01”, max=”2040–12–31")),
box(width = 6, background = “teal”,
br(), “ “,
dateInput(“end_date”, “Select End Date”, value = lastdate,
min = “2001–01–01”, max=”2040–12–31"))
),
# Output boxes for stats
fluidRow(
valueBoxOutput(“totconnd”, width =3),
valueBoxOutput(“firstconnd”, width =3),
valueBoxOutput(“ncompd”, width =3),
valueBoxOutput(“nposd”, width =3)),
# Plot outputs
fluidRow(
column(width = 6,
box(
width = 12, status = “info”, solidHeader = TRUE, background = “aqua”,
#title = “Connections by date”,
plotOutput(“lineplot”))),
column(width = 6,
box(
width = 12, status = “info”, solidHeader = TRUE, background = “aqua”,
#title = “Connections by year”,
plotOutput(“yearplot”)))
),
fluidRow(
# Output for Top 20 companies
column(width = 6,
box(
width = 12, status = “info”, solidHeader = TRUE, background = “aqua”,
#title = “Top Companies”,
plotOutput(“barcompdy”))),
# Output for Top 20 positions
column(width = 6,
box(
width = 12, status = “info”, solidHeader = TRUE, background = “aqua”,
#title = “Top Position”,
plotOutput(“barpostdy”)))),
# Raw table output
fluidRow(
box(
width = 12, solidHeader = TRUE,
title = “Filtered Table”,
DT::dataTableOutput(“linetable”))
)
)
),
# Link to my webiste
p(“To connect with me please visit my”,
a(“website”,
href = “https://jyoti05iitd.pagexl.com/”), align = “right”),
br(),
)ui <- dashboardPage(skin = “blue”,
header = header,
sidebar = sidebar,
body = body)server <- function(input, output) {
# Creating a filtered reactive data frame based on date selector
data_selected <- reactive({
dataem %>%
filter(connected_on >= input$start_date, connected_on <= input$end_date)
})
# Creating a reactive filtered data frame for count of connections by date
data_conn <- reactive({
dataem %>%
filter(connected_on >= input$start_date, connected_on <= input$end_date) %>%
group_by(connected_on) %>%
summarise(n = n()) %>%
ungroup()
})
# Creating a reactive filtered data frame for count of connections by year
data_year <- reactive({
dataem %>%
filter(connected_on >= input$start_date, connected_on <= input$end_date) %>%
group_by(connected_year) %>%
summarise(n = n()) %>%
ungroup()
})
# Creating a reactive filtered data frame for count of connections by company
data_comp <- reactive({
dataem %>%
filter(connected_on >= input$start_date, connected_on <= input$end_date) %>%
group_by(company) %>%
summarise(n = n()) %>%
arrange(desc(n)) %>%
ungroup() %>%
filter(company != ‘’) %>%
mutate(company = fct_reorder(company, desc(n)))
})
# Creating a reactive filtered data frame for count of connections by position
data_post <- reactive({
dataem %>%
filter(connected_on >= input$start_date, connected_on <= input$end_date) %>%
group_by(position) %>%
summarise(n = n()) %>%
arrange(desc(n)) %>%
ungroup() %>%
filter(position != ‘’) %>%
mutate(position = fct_reorder(position, desc(n)))
})
# Text Output at the top
output$journey <- renderValueBox({
valueBox(
value = paste(“My LinkedIn Journey from “, firstdate, “ to “, lastdate),
subtitle = “ “
#icon = icon(“route”)
)
})
# Total connections
output$totconnd <- renderValueBox({
valueBox(
value = nrow(data_selected()),
subtitle = “Total Connections”,
icon = icon(“users”),
color = “teal”
)
})
# First connection
output$firstconnd <- renderValueBox({
valueBox(
value = paste(firstname),
subtitle = “First connection”,
icon = icon(“user-tie”),
color = “teal”
)
})
# Count of different number of companies
output$ncompd <- renderValueBox({
valueBox(
value = nrow(data_comp()),
subtitle = “Number of companies”,
icon = icon(“building”),
color = “teal”
)
})
# Count of different number of positions
output$nposd <- renderValueBox({
valueBox(
value = nrow(data_post()),
subtitle = “Number of Positions”,
icon = icon(“user-tie”),
color = “teal”
)
})
# Line Plot showing number of connections for a day
output$lineplot <- renderPlot({
dataconn2 <- data_conn()
ggplot(dataconn2) +
geom_line(
mapping = aes(x = dataconn2[,1,drop=TRUE], y = dataconn2[,2,drop=TRUE],
col = colr), show.legend = FALSE
) +
labs(title = “Number of connections by date”,
x = “Date of connection”,
y = “Count of connections”) +
theme(panel.background = element_blank(),
legend.key = element_blank(),
legend.background = element_blank(),
strip.background = element_blank(),
plot.background = element_rect(fill = plotbk, color = “black”, size = 3),
panel.grid = element_blank(),
axis.line = element_line(color = “red”),
axis.ticks = element_line(color = “red”),
strip.text = element_text(size = 16, color = striptext),
axis.title.y = element_text(color = striptext, hjust = 0, face = “italic”),
axis.title.x = element_blank(),
axis.text = element_text(color = “black”, angle = 90),
legend.position = “none”)
})
# Bar plot showing number of connections for a year
output$yearplot <- renderPlot({
datayear <- data_year()
ggplot(datayear, aes(x = datayear[,1,drop=TRUE], y = datayear[,2,drop=TRUE])) +
geom_col(fill= colr) +
labs(title = “Number of connections by Year”,
x = “Year”,
y = “Count of connections”) +
#coord_flip() +
theme(panel.background = element_blank(),
legend.key = element_blank(),
legend.background = element_blank(),
strip.background = element_blank(),
plot.background = element_rect(fill = plotbk, color = “black”, size = 3),
panel.grid = element_blank(),
axis.line = element_line(color = “red”),
axis.ticks = element_line(color = “red”),
strip.text = element_text(size = 16, color = striptext),
axis.title.y = element_text(color = striptext, hjust = 0, face = “italic”),
axis.title.x = element_blank(),
axis.text = element_text(color = “black”, angle = 90),
legend.position = “none”)
})
# Bar plot showing Top 20 companies
output$barcompdy <- renderPlot({
datacomp2 <- data_comp() %>% head(20)
ggplot(datacomp2, aes(x = datacomp2[,1,drop=TRUE], y = datacomp2[,2,drop=TRUE])) +
geom_col(fill= colr) +
labs(title = “Top 20 companies of my connections”,
x = “Companies”,
y = “Count of connections”) +
#coord_flip() +
theme(panel.background = element_blank(),
legend.key = element_blank(),
legend.background = element_blank(),
strip.background = element_blank(),
plot.background = element_rect(fill = plotbk, color = “black”, size = 3),
panel.grid = element_blank(),
axis.line = element_line(color = “red”),
axis.ticks = element_line(color = “red”),
strip.text = element_text(size = 16, color = striptext),
axis.title.y = element_text(color = striptext, hjust = 0, face = “italic”),
axis.title.x = element_blank(),
axis.text = element_text(color = “black”, angle = 90),
legend.position = “none”)
})
# Bar plot showing Top 20 positions
output$barpostdy <- renderPlot({
datapost2 <- data_post() %>% head(20)
ggplot(datapost2, aes(x = datapost2[,1,drop=TRUE], y = datapost2[,2,drop=TRUE])) +
geom_col(fill= colr) +
labs(title = “Top 20 Positions of my connections”,
x = “Positions”,
y = “Count of connections”) +
#coord_flip() +
theme(panel.background = element_blank(),
legend.key = element_blank(),
legend.background = element_blank(),
strip.background = element_blank(),
plot.background = element_rect(fill = plotbk, color = “black”, size = 3),
panel.grid = element_blank(),
axis.line = element_line(color = “red”),
axis.ticks = element_line(color = “red”),
strip.text = element_text(size = 16, color = striptext),
axis.title.y = element_text(color = striptext, hjust = 0, face = “italic”),
axis.title.x = element_blank(),
axis.text = element_text(color = “black”, angle = 90),
legend.position = “none”)
})
# Raw table output
output$linetable <- DT::renderDataTable({
data_selected()
})
}shinyApp(ui, server)
The app is published on shinyapps.io at https://jyoti05iitd.shinyapps.io/ExploreLinkedInConn/
Please visit the app and add comments for improvements.