library(dplyr)
library(readxl)
library(lubridate)
library(timetk)
library(tidyr)
library(janitor)
library(stringr)
library(ggplot2)
library(healthyR.ts)
library(knitr)
library(kableExtra)
<- "linkedin_content.xlsx"
fp
<- read_excel(fp, sheet = "ENGAGEMENT") %>%
engagement_tbl clean_names() %>%
mutate(date = mdy(date)) %>%
mutate(`Engagement Rate` = (engagements / impressions) * 100) %>%
filter_by_time(
.date_var = date,
.end_date = "2023-12-31"
)
<- read_excel(fp, sheet = "TOP POSTS", skip = 1) %>%
top_posts_tbl clean_names()
<- read_excel(fp, sheet = "FOLLOWERS", skip = 2) %>%
followers_tbl clean_names() %>%
mutate(date = mdy(date)) %>%
filter_by_time(
.date_var = date,
.end_date = "2023-12-31"
)
<- read_excel(fp, sheet = "DEMOGRAPHICS") %>%
demographics_tbl clean_names()
Introduction
As we close the door on another year, it’s always a good time to look back and reflect on the past 12 months. And what better way to do that than with a LinkedIn Year in Review?
Whether you’re a job seeker, a business owner, or just someone who enjoys staying connected with their professional network, LinkedIn is an invaluable tool for staying up to date with the latest trends and opportunities in your field. And as we wrap up 2023, now is the perfect time to take a look at how you’ve been using LinkedIn and see where you can improve.
So what did your LinkedIn Year in Review have in store for you? Here are just a few of the things you might have seen:
- A summary of your activity on LinkedIn, including how many people you’ve connected with, how many posts you’ve shared, and how many likes, comments, and shares your content has received.
- A breakdown of the industries and job titles of the people you’ve connected with, which can give you a good idea of the types of people you’ve been spending the most time interacting with.
- A summary of your skills and endorsements, as well as which skills are most in demand in your industry.
All of these insights can be incredibly valuable as you start planning for the year ahead. With this information in hand, you can start looking for new opportunities, strengthening your existing relationships, and building new ones. And with the start of the new year, it’s a perfect time to set new goals and improve your LinkedIn profile.
If you haven’t yet checked out your LinkedIn Year in Review, don’t wait any longer! Log in to your account and take a look. And while you’re there, why not make a resolution to be more active on LinkedIn in the coming year? The more you put into your professional network, the more you’ll get out of it.
So let’s make the most of this new year, take advantage of the insights from your LinkedIn Year in Review, and make the most of your professional network. Here’s to a successful, connected, and productive 2024!
I have done a lot of work on this already, it is not comprehensive but it is enough to understand what is happening, and I used a lot of functionality from the {healthyverse}
Don’t forget you can also see my package and GitHub development wrap up on my year in review 2023
Analysis
I will do this in chunks, as it will be easier to digest. First of course you have to get your data. I am not going to go over this process as there are many a great link just a search away.
Let’s load in those libraries and read the files in.
Now let’s take a look at that data.
glimpse(engagement_tbl)
Rows: 365
Columns: 4
$ date <date> 2023-01-01, 2023-01-02, 2023-01-03, 2023-01-04, 202…
$ impressions <dbl> 4872, 3735, 10360, 12217, 27036, 26084, 8720, 2753, …
$ engagements <dbl> 34, 17, 51, 80, 173, 124, 32, 17, 80, 54, 106, 135, …
$ `Engagement Rate` <dbl> 0.6978654, 0.4551539, 0.4922780, 0.6548252, 0.639887…
glimpse(top_posts_tbl)
Rows: 50
Columns: 7
$ post_url_1 <chr> "https://www.linkedin.com/feed/update/urn:li:activ…
$ post_publish_date_2 <chr> "2/16/2023", "2/16/2023", "3/16/2023", "1/24/2023"…
$ engagements <dbl> 281, 227, 220, 194, 181, 172, 160, 145, 138, 124, …
$ x4 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
$ post_url_5 <chr> "https://www.linkedin.com/feed/update/urn:li:activ…
$ post_publish_date_6 <chr> "2/16/2023", "1/5/2023", "1/17/2023", "1/24/2023",…
$ impressions <dbl> 43951, 38656, 34402, 32505, 25205, 24916, 22656, 2…
glimpse(followers_tbl)
Rows: 365
Columns: 2
$ date <date> 2023-01-01, 2023-01-02, 2023-01-03, 2023-01-04, 2023-01…
$ new_followers <dbl> 11, 13, 17, 16, 26, 15, 14, 18, 14, 9, 11, 23, 6, 13, 5,…
glimpse(demographics_tbl)
Rows: 30
Columns: 3
$ top_demographics <chr> "Job titles", "Job titles", "Job titles", "Job titles…
$ value <chr> "Data Scientist", "Data Analyst", "Software Engineer"…
$ percentage <chr> "0.05210459977388382", "0.03567609563469887", "0.0223…
We are really only going to focus on the engagement_tbl and the followers_tbl as this is more of a time series analysis.
Ok, so let’s see how my Impressions, Engagements, and Engagement Rate have been.
%>%
engagement_tbl pivot_longer(cols = -date) %>%
mutate(name = str_to_title(name)) %>%
plot_time_series(
.facet_vars = name,
.value = value,
.date_var = date,
.interactive = FALSE,
.smooth = FALSE,
.title = "LinkedIn Stats Time Series Plot"
+
) theme_minimal()
%>%
followers_tbl plot_time_series(
.value = new_followers,
.date_var = date,
.interactive = FALSE,
.smooth = FALSE,
.title = "LinkedIn Stats Time Series Plot - New Followers"
+
) theme_minimal()
Let’s look at a cumulative view of things.
%>%
engagement_tbl summarise_by_time(
.date_var = date,
.by = "month",
`Cumulative Impressions` = sum(impressions),
`Cumulative Engagements` = sum(engagements)
%>%
) mutate(
`Cumulative Impressions` = cumsum(`Cumulative Impressions`),
`Cumulative Engagements` = cumsum(`Cumulative Engagements`)
%>%
) slice(1:12) %>%
pivot_longer(cols = -date) %>%
mutate(name = str_to_title(name)) %>%
ggplot(aes(x = date, y = value)) +
geom_col() +
facet_wrap(~ name, scales = "free") +
labs(
x = "Date",
y = "Value",
title = "LinkedIn Stats Time Series Plot"
+
) theme_minimal()
%>%
followers_tbl summarise_by_time(
.date_var = date,
.by = "month",
`Cumulative Followers` = sum(new_followers)
%>%
) mutate(
`Cumulative Followers` = cumsum(`Cumulative Followers`)
%>%
) slice(1:12) %>%
ggplot(aes(x = date, y = `Cumulative Followers`)) +
geom_col() +
labs(
x = "Date",
y = "Value",
title = "LinkedIn Stats Time Series Plot - New Followers"
+
) theme_minimal()
It seems again that writing blog posts and sharing them daily has a nice effect. Now we are going to look at some Value, Velocity, and Acceleration plots with the ts_vva_plot()
function from the {healthyR.ts
} package.
ts_vva_plot(engagement_tbl, date, engagements)$plots$static_plot
ts_vva_plot(engagement_tbl, date, impressions)$plots$static_plot
ts_vva_plot(engagement_tbl, date, `Engagement Rate`)$plots$static_plot
ts_vva_plot(followers_tbl, date, new_followers)$plots$static_plot
Now some simple moving average plots using the function ts_sma_plot()
again from the {healthyR.ts}
library.
ts_sma_plot(engagement_tbl, date, impressions, .sma_order = c(7, 14, 21, 30))$plots$static_plot
ts_sma_plot(engagement_tbl, date, engagements, .sma_order = c(7, 14, 21, 30))$plots$static_plot
ts_sma_plot(engagement_tbl, date, `Engagement Rate`, .sma_order = c(7, 14, 21, 30))$plots$static_plot
ts_sma_plot(followers_tbl, date, new_followers, .sma_order = c(7, 14, 21, 30))$plots$static_plot
Now some calendar heatmaps with ts_calendar_heatmap_plot()
ts_calendar_heatmap_plot(engagement_tbl, date, impressions, .interactive = FALSE) +
labs(title = "Calendar Heatmap - Impressions")
ts_calendar_heatmap_plot(engagement_tbl, date, engagements, .interactive = FALSE) +
labs(title = "Calendar Heatmap - Engagemets")
ts_calendar_heatmap_plot(engagement_tbl, date, `Engagement Rate`, .interactive = FALSE) +
labs(title = "Calendar Heatmap - Engagement Rate")
ts_calendar_heatmap_plot(followers_tbl, date, new_followers, .interactive = FALSE) +
labs(title = "Calendar Heatmap - New Followers")
Some seasonal diagnostics using {timetk}
plot_seasonal_diagnostics(engagement_tbl
.interactive = FALSE,
, date, engagements, .feature_set = c("wday.lbl", "month.lbl"),
.title = "Seasonal Diagnostics - Engagements") +
theme_minimal()
plot_seasonal_diagnostics(engagement_tbl
.interactive = FALSE,
, date, impressions, .feature_set = c("wday.lbl", "month.lbl"),
.title = "Seasonal Diagnostics - Impressions") +
theme_minimal()
plot_seasonal_diagnostics(engagement_tbl
`Engagement Rate`, .interactive = FALSE,
, date, .feature_set = c("wday.lbl", "month.lbl"),
.title = "Seasonal Diagnostics - Engagement Rate") +
theme_minimal()
plot_seasonal_diagnostics(
.interactive = FALSE,
followers_tbl, date, new_followers, .feature_set = c("wday.lbl","month.lbl"),
.title = "Seasonal Diagnostics - New Followers") +
theme_minimal()
Finally some lag correlation plots with ts_lag_correlation()
.
ts_lag_correlation(engagement_tbl, date, engagements, .lags = c(7, 14, 21, 28))$plots$lag_plot +
labs(title = "Lag Correlation Plot - Engagements") +
geom_smooth(se = FALSE, method = "lm", color = "black", linetype = "dashed")
ts_lag_correlation(engagement_tbl, date, impressions, .lags = c(7, 14, 21, 28))$plots$lag_plot +
labs(title = "Lag Correlation Plot - Impressions") +
geom_smooth(se = FALSE, method = "lm", color = "black", linetype = "dashed")
ts_lag_correlation(engagement_tbl, date, `Engagement Rate`, .lags = c(7, 14, 21, 28))$plots$lag_plot +
labs(title = "Lag Correlation Plot - Engagement Rate") +
geom_smooth(se = FALSE, method = "lm", color = "black", linetype = "dashed")
ts_lag_correlation(followers_tbl, date, new_followers, .lags = c(7, 14, 21, 28))$plots$lag_plot +
labs(title = "Lag Correlation Plot - New Followers") +
geom_smooth(se = FALSE, method = "lm", color = "black", linetype = "dashed")
Key Stats and Tables
Now we are going to look at some key stats and tables. First we will look at the top 10 posts by impressions.
%>%
top_posts_tbl select(post_publish_date_2, impressions, post_url_1) %>%
arrange(desc(impressions)) %>%
head(10) %>%
setNames(c("Post Date", "Impressions", "Post URL")) %>%
kable(caption = "Top 10 Posts by Impressions", align = "c")
Post Date | Impressions | Post URL |
---|---|---|
2/16/2023 | 43951 | https://www.linkedin.com/feed/update/urn:li:activity:7031977309351890944 |
2/16/2023 | 38656 | https://www.linkedin.com/feed/update/urn:li:activity:7031977249448820737 |
3/16/2023 | 34402 | https://www.linkedin.com/feed/update/urn:li:activity:7042173970149728257 |
1/24/2023 | 32505 | https://www.linkedin.com/feed/update/urn:li:activity:7023663053699207168 |
8/24/2023 | 25205 | https://www.linkedin.com/feed/update/urn:li:activity:7100535469263699968 |
1/17/2023 | 24916 | https://www.linkedin.com/feed/update/urn:li:activity:7021114787371614209 |
1/5/2023 | 22656 | https://www.linkedin.com/feed/update/urn:li:activity:7016769698595749888 |
3/10/2023 | 21943 | https://www.linkedin.com/feed/update/urn:li:activity:7039960379266883585 |
6/23/2023 | 20559 | https://www.linkedin.com/feed/update/urn:li:activity:7078000250656808960 |
2/21/2023 | 19730 | https://www.linkedin.com/feed/update/urn:li:activity:7033888693216018432 |
Now we will look at the top 10 posts by engagements.
%>%
top_posts_tbl select(post_publish_date_2, engagements, post_url_1) %>%
arrange(desc(engagements)) %>%
head(10) %>%
setNames(c("Post Date", "Engagements", "Post URL")) %>%
kable(caption = "Top 10 Posts by Engagements", align = "c")
Post Date | Engagements | Post URL |
---|---|---|
2/16/2023 | 281 | https://www.linkedin.com/feed/update/urn:li:activity:7031977309351890944 |
2/16/2023 | 227 | https://www.linkedin.com/feed/update/urn:li:activity:7031977249448820737 |
3/16/2023 | 220 | https://www.linkedin.com/feed/update/urn:li:activity:7042173970149728257 |
1/24/2023 | 194 | https://www.linkedin.com/feed/update/urn:li:activity:7023663053699207168 |
8/24/2023 | 181 | https://www.linkedin.com/feed/update/urn:li:activity:7100535469263699968 |
1/17/2023 | 172 | https://www.linkedin.com/feed/update/urn:li:activity:7021114787371614209 |
1/5/2023 | 160 | https://www.linkedin.com/feed/update/urn:li:activity:7016769698595749888 |
3/10/2023 | 145 | https://www.linkedin.com/feed/update/urn:li:activity:7039960379266883585 |
6/23/2023 | 138 | https://www.linkedin.com/feed/update/urn:li:activity:7078000250656808960 |
2/21/2023 | 124 | https://www.linkedin.com/feed/update/urn:li:activity:7033888693216018432 |
Now we will look at the top 10 posts by engagement rate.
%>%
top_posts_tbl select(post_publish_date_2, engagements, impressions, post_url_1) %>%
mutate(engagement_rate = engagements / impressions) %>%
arrange(desc(engagement_rate)) %>%
select(post_publish_date_2, engagement_rate, post_url_1) %>%
head(10) %>%
setNames(c("Post Date", "Engagement Rate", "Post URL")) %>%
kable(caption = "Top 10 Posts by Engagement Rate", align = "c")
Post Date | Engagement Rate | Post URL |
---|---|---|
8/24/2023 | 0.0071811 | https://www.linkedin.com/feed/update/urn:li:activity:7100535469263699968 |
1/5/2023 | 0.0070621 | https://www.linkedin.com/feed/update/urn:li:activity:7016769698595749888 |
1/17/2023 | 0.0069032 | https://www.linkedin.com/feed/update/urn:li:activity:7021114787371614209 |
5/10/2023 | 0.0068692 | https://www.linkedin.com/feed/update/urn:li:activity:7062043144850137088 |
2/6/2023 | 0.0067925 | https://www.linkedin.com/feed/update/urn:li:activity:7028379188441010176 |
7/17/2023 | 0.0067441 | https://www.linkedin.com/feed/update/urn:li:activity:7086688278245961728 |
11/29/2023 | 0.0067365 | https://www.linkedin.com/feed/update/urn:li:activity:7135620032557940736 |
6/23/2023 | 0.0067124 | https://www.linkedin.com/feed/update/urn:li:activity:7078000250656808960 |
1/25/2023 | 0.0066225 | https://www.linkedin.com/feed/update/urn:li:activity:7024095415348133889 |
3/10/2023 | 0.0066080 | https://www.linkedin.com/feed/update/urn:li:activity:7039960379266883585 |
Total Impressions: 2,720,605
Total Engagements: 20,000
Mean Engagement Rate: 0.0073513
New Followers: 6,388
And finally the demographics of people who typically interact with my posts:
%>%
demographics_tbl mutate(percentage = substr(percentage, 1, 4)) %>%
kable(
caption = "Demographics of People Who Interact With My Posts",
align = "c"
)
top_demographics | value | percentage |
---|---|---|
Job titles | Data Scientist | 0.05 |
Job titles | Data Analyst | 0.03 |
Job titles | Software Engineer | 0.02 |
Job titles | Data Engineer | 0.01 |
Job titles | Professor | 0.01 |
Locations | New York City Metropolitan Area | 0.06 |
Locations | Greater Bengaluru Area | 0.03 |
Locations | Greater Delhi Area | 0.02 |
Locations | Pune/Pimpri-Chinchwad Area | 0.02 |
Locations | Mumbai Metropolitan Region | 0.01 |
Industries | IT Services and IT Consulting | 0.22 |
Industries | Software Development | 0.11 |
Industries | Higher Education | 0.05 |
Industries | Financial Services | 0.05 |
Industries | Hospitals and Health Care | 0.05 |
Seniority | Senior | 0.33 |
Seniority | Entry | 0.27 |
Seniority | Director | 0.03 |
Seniority | Manager | 0.03 |
Seniority | Training | 0.02 |
Company size | 10,001+ employees | 0.17 |
Company size | 1001-5000 employees | 0.10 |
Company size | 51-200 employees | 0.08 |
Company size | 11-50 employees | 0.08 |
Company size | 1-10 employees | 0.06 |
Companies | Tata Consultancy Services | < 1% |
Companies | Long Island Community Hospital | < 1% |
Companies | Amazon | < 1% |
Companies | EY | < 1% |
Companies | Citi | < 1% |
Voila!