The data used in this project is from an anonymous organisation’s social media ad campaign hosted on Facebook. More information about the data set can be found linked here
This funnel analysis evaluates the performance of multiple digital advertising campaigns that was hosted on Facebook by an anonymous company. Success of ad campaigns was based on sales information like impressions, clicks, approved conversions and cost per approved conversions. The goal was to identify which demographic groups and ad campaigns most effectively drive users through the marketing funnel while optimizing return on ad spend. Insights from this analysis may help publishers make data-driven decisions on how best to retain advertisers and maximize publisher revenue. An additional potential benefit of this campaign is that provided insights are intended to also increase revenue of advertisers which may help with scaling publishers’ growth initiatives.
Packages like tidyverse contain core functions that are useful for data analysis in R. If you have not already installed the essential packages, make sure to do so before this step by using the install.packages function. The install packages step cannot be included in this RMarkdown due to a CRAN mirror issue.
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.5.2 ✔ tibble 3.3.0
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.1.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("DT")
After downloading the data set to your local computer, find the file name and make sure you enter it exactly when using the read_csv function.
ad_campaign_df <- read_csv("KAG_conversion_data.csv")
## Rows: 1143 Columns: 11
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): age, gender
## dbl (9): ad_id, xyz_campaign_id, fb_campaign_id, interest, Impressions, Clic...
##
## ℹ 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.
Use the head function to understand the different datatypes and structure of the data.
head(ad_campaign_df)
## # A tibble: 6 × 11
## ad_id xyz_campaign_id fb_campaign_id age gender interest Impressions Clicks
## <dbl> <dbl> <dbl> <chr> <chr> <dbl> <dbl> <dbl>
## 1 708746 916 103916 30-34 M 15 7350 1
## 2 708749 916 103917 30-34 M 16 17861 2
## 3 708771 916 103920 30-34 M 20 693 0
## 4 708815 916 103928 30-34 M 28 4259 1
## 5 708818 916 103928 30-34 M 28 4133 1
## 6 708820 916 103929 30-34 M 29 1915 0
## # ℹ 3 more variables: Spent <dbl>, Total_Conversion <dbl>,
## # Approved_Conversion <dbl>
Use the colnames function to know which column names to enter when you later run aggregate functions.
colnames(ad_campaign_df)
## [1] "ad_id" "xyz_campaign_id" "fb_campaign_id"
## [4] "age" "gender" "interest"
## [7] "Impressions" "Clicks" "Spent"
## [10] "Total_Conversion" "Approved_Conversion"
Analyze overall engagement KPIs for the entire data set.
# ---- Engagement KPIs Overall ----
engagement_kpis <- ad_campaign_df %>%
summarise(
Total_Impressions = sum(Impressions, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
CTR = (Total_Clicks / Total_Impressions) * 100,
Avg_Clicks_per_Campaign = mean(Clicks, na.rm = TRUE)
)
datatable(engagement_kpis)
Analyze engagement KPIs by the age segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Engagement KPIs by age ----
engagement_by_age <- ad_campaign_df %>%
group_by(age) %>%
summarise(
Impressions = sum(Impressions, na.rm = TRUE),
Clicks = sum(Clicks, na.rm = TRUE),
CTR = (Clicks / Impressions) * 100
) %>%
arrange(desc(CTR))
datatable(engagement_by_age)
Analyze engagement KPIs by the gender segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Engagement KPIs by gender ----
engagement_by_gender <- ad_campaign_df %>%
group_by(gender) %>%
summarise(
Impressions = sum(Impressions, na.rm = TRUE),
Clicks = sum(Clicks, na.rm = TRUE),
CTR = (Clicks / Impressions) * 100
) %>%
arrange(desc(CTR))
datatable(engagement_by_gender)
Analyze engagement KPIs by the interest segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Engagement KPIs by interest ----
engagement_by_interest <- ad_campaign_df %>%
group_by(interest) %>%
summarise(
Impressions = sum(Impressions, na.rm = TRUE),
Clicks = sum(Clicks, na.rm = TRUE),
CTR = (Clicks / Impressions) * 100
) %>%
arrange(desc(CTR))
datatable(engagement_by_interest)
Analyze engagement KPIs by the campaign segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Engagement KPIs by campaign ----
engagement_by_campaign <- ad_campaign_df %>%
group_by(xyz_campaign_id) %>%
summarise(
Impressions = sum(Impressions, na.rm = TRUE),
Clicks = sum(Clicks, na.rm = TRUE),
CTR = (Clicks / Impressions) * 100
) %>%
arrange(desc(CTR))
datatable(engagement_by_campaign)
Analyze overall conversion KPIs for the entire data set.
# ---- Conversion KPIs Overall ----
conversion_kpis <- ad_campaign_df %>%
summarise(
Total_Conversions = sum(Total_Conversion, na.rm = TRUE),
Total_Approved_Conversions = sum(Approved_Conversion, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
Conversion_Rate = (Total_Conversions / Total_Clicks) * 100,
Approved_Conversion_Rate = (Total_Approved_Conversions / Total_Clicks) * 100,
Approval_to_Total_Ratio = (Total_Approved_Conversions / Total_Conversions)
)
datatable(conversion_kpis)
Analyze conversion KPIs by the age segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Conversion KPIs by age ----
conversion_kpis_age <- ad_campaign_df %>%
group_by(age) %>%
summarise(
Total_Conversions = sum(Total_Conversion, na.rm = TRUE),
Total_Approved_Conversions = sum(Approved_Conversion, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
Conversion_Rate = (Total_Conversions / Total_Clicks) * 100,
Approved_Conversion_Rate = (Total_Approved_Conversions / Total_Clicks) * 100,
Approval_to_Total_Ratio = (Total_Approved_Conversions / Total_Conversions)
) %>%
arrange(desc(Approved_Conversion_Rate))
datatable(conversion_kpis_age)
Analyze conversion KPIs by the gender segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Conversion KPIs by gender ----
conversion_kpis_gender <- ad_campaign_df %>%
group_by(gender) %>%
summarise(
Total_Conversions = sum(Total_Conversion, na.rm = TRUE),
Total_Approved_Conversions = sum(Approved_Conversion, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
Conversion_Rate = (Total_Conversions / Total_Clicks) * 100,
Approved_Conversion_Rate = (Total_Approved_Conversions / Total_Clicks) * 100,
Approval_to_Total_Ratio = (Total_Approved_Conversions / Total_Conversions)
) %>%
arrange(desc(Approved_Conversion_Rate))
datatable(conversion_kpis_gender)
Analyze conversion KPIs by the interst segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Conversion KPIs by interest ----
conversion_kpis_interest <- ad_campaign_df %>%
group_by(interest) %>%
summarise(
Total_Conversions = sum(Total_Conversion, na.rm = TRUE),
Total_Approved_Conversions = sum(Approved_Conversion, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
Conversion_Rate = (Total_Conversions / Total_Clicks) * 100,
Approved_Conversion_Rate = (Total_Approved_Conversions / Total_Clicks) * 100,
Approval_to_Total_Ratio = (Total_Approved_Conversions / Total_Conversions)
) %>%
arrange(desc(Approved_Conversion_Rate))
datatable(conversion_kpis_interest)
Analyze conversion KPIs by the campaign segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Conversion KPIs by campaign ----
conversion_kpis_campaign <- ad_campaign_df %>%
group_by(xyz_campaign_id) %>%
summarise(
Total_Conversions = sum(Total_Conversion, na.rm = TRUE),
Total_Approved_Conversions = sum(Approved_Conversion, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
Conversion_Rate = (Total_Conversions / Total_Clicks) * 100,
Approved_Conversion_Rate = (Total_Approved_Conversions / Total_Clicks) * 100,
Approval_to_Total_Ratio = (Total_Approved_Conversions / Total_Conversions)
) %>%
arrange(desc(Approved_Conversion_Rate))
datatable(conversion_kpis_campaign)
Analyze overall spend KPIs for the entire data set.
# ---- Spend KPIs Overall ----
spend_kpis <- ad_campaign_df %>%
summarise(
Total_Spend = sum(Spent, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
Total_Conversions = sum(Total_Conversion, na.rm = TRUE),
Total_Approved_Conversions = sum(Approved_Conversion, na.rm = TRUE),
CPC = Total_Spend / Total_Clicks,
Cost_per_Conversion = Total_Spend / Total_Conversions,
Cost_per_Approved_Conversion = Total_Spend / Total_Approved_Conversions
)
datatable(spend_kpis)
Analyze spend KPIs by the age segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Spend KPIs by age ----
spend_kpis_age <- ad_campaign_df %>%
group_by(age) %>%
summarise(
Total_Spend = sum(Spent, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
Total_Conversions = sum(Total_Conversion, na.rm = TRUE),
Total_Approved_Conversions = sum(Approved_Conversion, na.rm = TRUE),
CPC = Total_Spend / Total_Clicks,
Cost_per_Conversion = Total_Spend / Total_Conversions,
Cost_per_Approved_Conversion = Total_Spend / Total_Approved_Conversions
) %>%
arrange(Cost_per_Approved_Conversion)
datatable(spend_kpis_age)
Analyze spend KPIs by the gender segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Spend KPIs by gender ----
spend_kpis_gender <- ad_campaign_df %>%
group_by(gender) %>%
summarise(
Total_Spend = sum(Spent, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
Total_Conversions = sum(Total_Conversion, na.rm = TRUE),
Total_Approved_Conversions = sum(Approved_Conversion, na.rm = TRUE),
CPC = Total_Spend / Total_Clicks,
Cost_per_Conversion = Total_Spend / Total_Conversions,
Cost_per_Approved_Conversion = Total_Spend / Total_Approved_Conversions
) %>%
arrange(Cost_per_Approved_Conversion)
datatable(spend_kpis_gender)
Analyze spend KPIs by the interest segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Spend KPIs by interest ----
spend_kpis_interest <- ad_campaign_df %>%
group_by(interest) %>%
summarise(
Total_Spend = sum(Spent, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
Total_Conversions = sum(Total_Conversion, na.rm = TRUE),
Total_Approved_Conversions = sum(Approved_Conversion, na.rm = TRUE),
CPC = Total_Spend / Total_Clicks,
Cost_per_Conversion = Total_Spend / Total_Conversions,
Cost_per_Approved_Conversion = Total_Spend / Total_Approved_Conversions
) %>%
arrange(Cost_per_Approved_Conversion)
datatable(spend_kpis_interest)
Analyze spend KPIs by the campaign segment by utilizing the group_by, summarise, aggregate, and arrange functions to surface trends in the data.
# ---- Spend KPIs by campaign ----
spend_kpis_campaign <- ad_campaign_df %>%
group_by(xyz_campaign_id) %>%
summarise(
Total_Spend = sum(Spent, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
Total_Conversions = sum(Total_Conversion, na.rm = TRUE),
Total_Approved_Conversions = sum(Approved_Conversion, na.rm = TRUE),
CPC = Total_Spend / Total_Clicks,
Cost_per_Conversion = Total_Spend / Total_Conversions,
Cost_per_Approved_Conversion = Total_Spend / Total_Approved_Conversions
) %>%
arrange(Cost_per_Approved_Conversion)
datatable(spend_kpis_campaign)
Analyze audience KPIs for the entire data set broken down by each campaign.
audience_campaign_kpis_campaign <- ad_campaign_df %>%
group_by(xyz_campaign_id) %>%
summarise(
Avg_Impressions_per_Campaign = mean(Impressions, na.rm = TRUE),
Avg_Spend_per_Campaign = mean(Spent, na.rm = TRUE),
Total_Spend_per_Campaign = sum(Spent, na.rm = TRUE)
)
datatable(audience_campaign_kpis_campaign)
Analyze market segments for top performers to surface trends in the data based on specific demographic combinations.Utilize the group_by, summarise, aggregate, arrange, and filter functions to ensure the data is clean and surface trends.
top_performers <- ad_campaign_df %>%
group_by(xyz_campaign_id, age, gender, interest) %>%
summarise(
Total_Impressions = sum(Impressions, na.rm = TRUE),
Total_Clicks = sum(Clicks, na.rm = TRUE),
Total_Conversions = sum(Total_Conversion, na.rm = TRUE),
Total_Approved_Conversions = sum(Approved_Conversion, na.rm = TRUE),
CTR = (Total_Clicks / Total_Impressions) * 100,
Conversion_Rate = (Total_Conversions / Total_Clicks) * 100,
Approved_Conversion_Rate = (Total_Approved_Conversions / Total_Clicks) * 100
) %>%
arrange(desc(Approved_Conversion_Rate)) %>%
filter(!is.infinite(Conversion_Rate),
!is.infinite(Approved_Conversion_Rate))
## `summarise()` has grouped output by 'xyz_campaign_id', 'age', 'gender'. You can
## override using the `.groups` argument.
datatable(top_performers)