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")
)