library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.6
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.1 ✔ tibble 3.3.0
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.2.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
data <- read.csv("marketing_campaign_performance_10000.csv")
data <- data %>%
mutate(
CTR = (Clicks/Impressions)*100,
ConversionRate = (Conversions/Clicks)*100
)
channel_summary <- data %>%
group_by(Channel) %>%
summarise(
Campaigns = n(),
Impressions = sum(Impressions),
Clicks = sum(Clicks),
Leads = sum(Leads),
Conversions = sum(Conversions),
Revenue = sum(Revenue_USD),
Cost = sum(Cost_USD),
Avg_CTR = mean(CTR),
Avg_Conversion = mean(ConversionRate),
Avg_ROI = mean(ROI)
)
channel_summary
## # A tibble: 5 × 11
## Channel Campaigns Impressions Clicks Leads Conversions Revenue Cost Avg_CTR
## <chr> <int> <int> <int> <int> <int> <dbl> <dbl> <dbl>
## 1 Display 2069 309367070 1.69e7 5.10e6 2057607 1.07e7 5.34e6 5.43
## 2 Email 1996 309167794 1.71e7 5.18e6 2076423 1.01e7 5.07e6 5.46
## 3 Influe… 2056 322458407 1.75e7 5.26e6 2101198 1.06e7 5.28e6 5.47
## 4 Search 1924 288572424 1.59e7 4.84e6 1951752 9.90e6 4.92e6 5.52
## 5 Social 1955 293040684 1.60e7 4.74e6 1920020 9.73e6 4.92e6 5.44
## # ℹ 2 more variables: Avg_Conversion <dbl>, Avg_ROI <dbl>
4.1 Campaign Distribution by Marketing Channel (Pie Chart)
library(tidyverse)
library(scales)
##
## Attaching package: 'scales'
## The following object is masked from 'package:purrr':
##
## discard
## The following object is masked from 'package:readr':
##
## col_factor
campaign_dist <- data %>%
count(Channel, name = "Campaigns") %>%
mutate(
Percentage = Campaigns / sum(Campaigns) * 100,
Label = paste0(
Channel,
"\n",
Campaigns, " Campaigns",
"\n(",
round(Percentage, 2),
"%)"
)
) %>%
arrange(desc(Campaigns)) %>%
mutate(
ypos = cumsum(Campaigns) - 0.5 * Campaigns
)
ggplot(campaign_dist,
aes(x = "", y = Campaigns, fill = Channel)) +
geom_col(
width = 1,
color = "white"
) +
coord_polar(theta = "y") +
geom_text(
aes(
y = ypos,
label = Label
),
size = 3,
lineheight = 0.9
) +
labs(
title = "Campaign Distribution by Marketing Channel",
fill = "Marketing Channel"
) +
theme_void() +
theme(
plot.title = element_text(
hjust = 0.5,
face = "bold",
size = 14
),
legend.position = "right"
)

4.2 Total Impressions by Marketing Channel (Horizontal Bar
Chart)
library(ggplot2)
library(scales)
ggplot(
channel_summary,
aes(
x = reorder(Channel, Impressions),
y = Impressions
)
) +
geom_col() +
coord_flip() +
geom_text(
aes(label = comma(Impressions)),
hjust = 1
) +
scale_y_continuous(labels = comma) +
labs(
title = "Total Impressions by Marketing Channel",
x = "",
y = "Impressions"
) +
theme_minimal()

4.3 Average CTR by Marketing Channel (Lollipop Chart)
ggplot(
channel_summary,
aes(
x = reorder(Channel, Avg_CTR),
y = Avg_CTR
)
) +
geom_segment(
aes(
xend = Channel,
y = 0,
yend = Avg_CTR
)
) +
geom_point(size = 5) +
geom_text(
aes(label = round(Avg_CTR,2)),
nudge_y = 1
) +
coord_flip() +
labs(
title = "Average CTR by Marketing Channel",
y = "CTR (%)",
x = ""
) +
theme_minimal()

4.4 Lead Generation by Marketing Channel (Bar Chart)
ggplot(
channel_summary,
aes(
x = reorder(Channel, Leads),
y = Leads
)
) +
geom_col() +
geom_text(
aes(label = comma(Leads)),
hjust = 1
) +
coord_flip() +
scale_y_continuous(labels = comma) +
labs(
title = "Lead Generation by Marketing Channel",
y = "Leads"
) +
theme_minimal()

4.5 Leads vs Conversions (Bubble Chart)
ggplot(
channel_summary,
aes(
x = Leads,
y = Conversions,
size = Revenue,
label = Channel
)
) +
geom_point(alpha = 0.7) +
geom_text(nudge_y = 50000) +
scale_x_continuous(labels = comma) +
scale_y_continuous(labels = comma) +
labs(
title = "Leads vs Conversions",
x = "Leads",
y = "Conversions"
) +
theme_minimal()

4.6 Conversion Rate by Channel (Funnel Chart)
library(plotly)
## Warning: package 'plotly' was built under R version 4.5.3
##
## Attaching package: 'plotly'
## 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
plot_ly(
type = "funnel",
y = channel_summary$Channel,
x = round(channel_summary$Avg_Conversion,2)
) %>%
layout(
title = "Conversion Rate by Channel"
)
4.7 Revenue Generated by Marketing Channel (Treemap)
library(treemapify)
## Warning: package 'treemapify' was built under R version 4.5.3
ggplot(
channel_summary,
aes(
area = Revenue,
fill = Revenue,
label = paste0(
Channel,"\n$",
comma(round(Revenue))
)
)
) +
geom_treemap() +
geom_treemap_text(
colour = "white",
place = "centre"
) +
labs(
title = "Revenue Generated by Marketing Channel"
)

4.8 Cost vs Revenue Analysis (Scatter Plot)
ggplot(
data,
aes(
x = Cost_USD,
y = Revenue_USD
)
) +
geom_point(alpha = 0.3) +
geom_smooth(
method = "lm",
se = FALSE
) +
labs(
title = "Cost vs Revenue Analysis",
subtitle = "Correlation ≈ 0.86",
x = "Cost (USD)",
y = "Revenue (USD)"
) +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

4.9 Average ROI by Marketing Channel (Box Plot)
ggplot(
data,
aes(
x = Channel,
y = ROI
)
) +
geom_boxplot() +
stat_summary(
fun = mean,
geom = "point",
size = 5
) +
labs(
title = "ROI Distribution by Marketing Channel",
y = "ROI"
) +
theme_minimal()

4.10 Distribution of ROI (Box Plot)
ggplot(
data,
aes(
x = "",
y = ROI
)
) +
geom_boxplot() +
labs(
title = "Overall ROI Distribution",
y = "ROI"
) +
theme_minimal()

4.11 Interactive ROI Dashboard (Plotly)
library(plotly)
plot_ly(
channel_summary,
x = ~Channel,
y = ~Avg_ROI,
type = "bar",
text = round(channel_summary$Avg_ROI,3),
textposition = "outside"
) %>%
layout(
title = "Interactive ROI Dashboard",
xaxis = list(title = "Channel"),
yaxis = list(title = "Average ROI")
)