Este cuaderno visualiza el reparto de publicidad del Ayuntamiento de Madrid

Cargar librerías

if(!"tidyverse" %in% installed.packages()) {install.packages("tidyverse")}
if(!"readxl" %in% installed.packages()) {install.packages("readxl")}
if(!"waffle" %in% installed.packages()) {install.packages("waffle")}
if(!"RColorBrewer" %in% installed.packages()) {install.packages("RColorBrewer")}
library("tidyverse")
library("readxl")
library("waffle")
library("RColorBrewer")

locale(date_names = "es", date_format = "%AD", time_format = "%AT",
  decimal_mark = ",", grouping_mark = ".", tz = "Europe/Berlin",
  encoding = "UTF-8", asciify = FALSE)
## <locale>
## Numbers:  123.456,78
## Formats:  %AD / %AT
## Timezone: Europe/Berlin
## Encoding: UTF-8
## <date_names>
## Days:   domingo (dom.), lunes (lun.), martes (mar.), miércoles (mié.), jueves
##         (jue.), viernes (vie.), sábado (sáb.)
## Months: enero (ene.), febrero (feb.), marzo (mar.), abril (abr.), mayo (may.),
##         junio (jun.), julio (jul.), agosto (ago.), septiembre (sept.),
##         octubre (oct.), noviembre (nov.), diciembre (dic.)
## AM/PM:  a. m./p. m.
Sys.setlocale(category = "LC_ALL", locale = "spanish")
## [1] "LC_COLLATE=Spanish_Spain.1252;LC_CTYPE=Spanish_Spain.1252;LC_MONETARY=Spanish_Spain.1252;LC_NUMERIC=C;LC_TIME=Spanish_Spain.1252"

Plantilla diseño

my_theme <- function(
  base_size = 11,
  base_color = "#5a5856",
  base_family = "sans"
  )
{
  # Establecemos la proporción del tamaño de la letra de cada uno de los elementos
  template <- 
    theme_bw(base_size=base_size, base_family = base_family) +
    theme(
      panel.border = element_blank(),
      panel.grid.major = element_blank(),
      panel.grid.minor = element_blank(),
      plot.title = element_text(
        size = base_size+2,
        face = "bold",
        color = base_color,
        vjust = 1.25, 
        hjust = 0.5),
      plot.subtitle = element_text(size=base_size + 2, color = base_color, hjust = 0.5),
      plot.caption = element_text(hjust = 1, size=base_size - 1, color = base_color),
      legend.position ="top",
      legend.margin =  margin(0,0,0,0,unit="pt"),
      legend.text = element_text(size=base_size + 1),
      text = element_text(size=base_size, color = base_color),
      axis.title.x = element_text(
        size=base_size + 1,
        vjust=0,
        color = base_color,
        margin = unit(c(3, 0, 0, 0), "mm")
      ),
      axis.title.y = element_text(
        size=base_size + 1, 
        vjust=1.25,
        color = base_color,
        margin = unit(c(0, 3, 0, 0), "mm")
      ),
      axis.title.y.right=element_text(
        size=base_size + 1,
        color = base_color,
        margin = unit(c(0, 0, 0, 3), "mm")
      ),
      axis.text.x = element_text(size=base_size - 1, color = base_color),
      axis.text.y = element_text(size=base_size-1,color = base_color),
      strip.text = element_text(size=base_size + 2, color = base_color),
      strip.text.x = element_text(size=base_size + 1, color = base_color),
      strip.text.y = element_text(size=base_size + 1, color = base_color),
      strip.background = element_rect(color = NA, fill = NA)
    )
  return(template)
}

Leer y preparar datos

# Descargar datos de esta URL https://datos.madrid.es/egob/catalogo/300024-30-publicidad-institucional.xlsx
# Precisa descarga, no se puede leer en línea
RRSS <- c("TWITTER","YOUTUBE","FACEBOOK + INSTAGRAM","SPOTIFY","TIKTOK")
publicidad_ayto_file <-  "publicidad_institucional_2023.xlsx"
publicidad_ayto <- read_excel (publicidad_ayto_file, sheet = "UNIDAD_MEDIO_SOPORTE_€_TRIMESTR" ) %>%
  mutate(MEDIO = ifelse(SOPORTE %in% RRSS,"RRSS", MEDIO)) %>%
  group_by(SOPORTE,MEDIO) %>%
    summarise( total = sum(`IMPORTE SIN IVA`)) %>%
  ungroup() %>%
  arrange (desc(total))

total_publicidad <- round(sum(publicidad_ayto$total),2)
total_x_medio <- publicidad_ayto %>%
  group_by(MEDIO) %>%
    summarise(total_medio = sum(total)) %>%
  ungroup()
x <- round(total_x_medio[match("RRSS",total_x_medio$MEDIO),]$total_medio,1)

Publicidad por medio

paleta_medios <- brewer.pal(7,'Set2')  # Paleta divergente
medios  <- publicidad_ayto %>%
  group_by (MEDIO) %>%
  summarise(
    euros = sum(total),
    percent = round (euros / total_publicidad * 100, 1)
  ) %>%
  ungroup() %>%
 arrange (desc(euros))

order_medios <- unique(medios$MEDIO)
medios$MEDIO <- factor(medios$MEDIO, levels = order_medios)
ggplot(
  data = medios,
  aes(fill = MEDIO, values = percent)) +
  geom_waffle(
    color = "white", size = 0.33,
    make_proportional = TRUE, n_rows = 10,
    radius = unit(3, "pt")
  ) +
  expand_limits(x = c(0,0), y = c(0,0)) +
  coord_equal() +
  labs(
    title = "Reparto de publicidad del Ayto. Madrid por medios",
    x = "",
    y = "",
    caption = "Fuente: https://datos.madrid.es / @congosto."
  ) +
  scale_fill_manual(values = paleta_medios) +
  my_theme() +
  theme_enhance_waffle() +
  theme(
    legend.position = "right",
    axis.ticks = element_blank()
  ) 

Función de repartos por soporte

reparto_soporte <- function(df, soporte){
  total_soporte <- round(total_x_medio[match(soporte,total_x_medio$MEDIO),]$total_medio,1)
  paleta_soporte <- brewer.pal(11,'Paired')  # Paleta divergente
  df  <- df %>%
  filter(MEDIO == soporte) %>%
  group_by (SOPORTE) %>%
  summarise(
    euros = sum(total),
    percent = round (euros / total_soporte * 100, 1)
  ) %>%
  ungroup() %>%
 arrange (desc(euros)) %>%
 head (10)
# Calculamos resto
total_top <- sum(df$euros)
row <- as_tibble_row(
  list(
    SOPORTE = "Resto",
    euros = total_soporte - total_top,
    percent = round ((total_soporte - total_top) / total_soporte * 100, 1)
  ))
df <- df %>% add_row(row)
order_soporte <- unique(df$SOPORTE)
df$SOPORTE <- factor(df$SOPORTE, levels = order_soporte)
p <- ggplot(
  data = df,
  aes(fill = SOPORTE, values = percent)) +
  geom_waffle(
    color = "white", size = 0.33,
    make_proportional = TRUE, n_rows = 10,
    radius = unit(3, "pt")
  ) +
  expand_limits(x = c(0,0), y = c(0,0)) +
  coord_equal() +
  labs(
    title = paste("Reparto de publicidad del Ayto. Madrid en", soporte),
    x = "",
    y = "",
    caption = "Fuente: https://datos.madrid.es / @congosto."
  ) +
  scale_fill_manual(values = paleta_soporte) +
  my_theme() +
  theme_enhance_waffle() +
  theme(
    legend.position = "right",
    axis.ticks = element_blank()
  ) 
  return (p)
}

Reparto de publicidad en INTERNET

p <- reparto_soporte(publicidad_ayto, "INTERNET")
print (p)

Reparto de publicidad en RADIO

p <- reparto_soporte(publicidad_ayto, "RADIO")
print (p)

### Reparto de publicidad en EXTERIOR

p <- reparto_soporte(publicidad_ayto, "EXTERIOR")
print (p)

Reparto de publicidad en PRENSA

p <- reparto_soporte(publicidad_ayto, "PRENSA")
print (p)

Reparto de publicidad en RRSS

p <- reparto_soporte(publicidad_ayto, "RRSS")
print (p)

Reparto de publicidad en TELEVISION

p <- reparto_soporte(publicidad_ayto, "TELEVISION")
print (p)

Reparto de publicidad en REVISTAS

p <- reparto_soporte(publicidad_ayto, "REVISTAS")
print (p)