ggplot2 (V): mini caso práctico

Iniciación a ggplot2: Guía para crear visualizaciones en R

Author

Roberto Gil-Saura

Published

September 9, 2025

Introducción

¡Bienvenido al post final de nuestra serie de iniciación a ggplot2! A lo largo de estos cuatro breves posts, hemos pasado de no escribir una sola línea de código a dominar los conceptos que hacen de ggplot2 una herramienta tan poderosa.

  1. En el Post I, aprendimos la Gramática de los Gráficos, la filosofía que sustenta todo lo que hacemos.
  2. En el Post II, construimos los gráficos esenciales: barras, líneas e histogramas.
  3. En el Post III, aprendimos a dar vida a nuestras visualizaciones con colores, etiquetas y títulos.
  4. Y en el Post IV, descubrimos el poder de las facetas para contar historias complejas.

Ahora, es el momento de unirlo todo. En este post de graduación, no aprenderemos (casi) ninguna función nueva. En su lugar, nos enfrentaremos a un caso práctico completo. Cogeremos un nuevo conjunto de datos, formularemos una pregunta de negocio y construiremos una visualización final, compleja y pulida, paso a paso, aplicando todo lo que hemos aprendido.

Este es el momento de ver cómo todas las piezas del puzle encajan para transformar datos brutos en un insight visual claro y convincente.

El caso práctico: Analizando datos de propinas

Para nuestro proyecto final, utilizaremos el dataset tips del paquete ggplot2. Este conjunto de datos contiene información sobre las propinas dejadas en un restaurante.

Nuestra pregunta de negocio será: “¿Qué factores influyen en el porcentaje de propina que dejan los clientes? ¿Importa el día de la semana, el tamaño del grupo o si el cliente es fumador?”

Paso 1: Explorar los datos

Primero, carguemos las librerías y echemos un vistazo a nuestros datos.

Code
# Cargar la librería
library(tidyverse)
library(reshape2)

# Echar un vistazo al dataset 'tips'
glimpse(tips)
Rows: 244
Columns: 7
$ total_bill <dbl> 16.99, 10.34, 21.01, 23.68, 24.59, 25.29, 8.77, 26.88, 15.0…
$ tip        <dbl> 1.01, 1.66, 3.50, 3.31, 3.61, 4.71, 2.00, 3.12, 1.96, 3.23,…
$ sex        <fct> Female, Male, Male, Male, Female, Male, Male, Male, Male, M…
$ smoker     <fct> No, No, No, No, No, No, No, No, No, No, No, No, No, No, No,…
$ day        <fct> Sun, Sun, Sun, Sun, Sun, Sun, Sun, Sun, Sun, Sun, Sun, Sun,…
$ time       <fct> Dinner, Dinner, Dinner, Dinner, Dinner, Dinner, Dinner, Din…
$ size       <int> 2, 3, 3, 2, 4, 4, 2, 4, 2, 2, 2, 4, 2, 4, 2, 2, 3, 3, 3, 3,…

Tenemos variables clave como total_bill (factura total), tip (propina), sex (sexo del pagador), smoker (si era fumador), day (día de la semana), time (comida o cena) y size (tamaño del grupo).

Un buen primer paso es crear una nueva variable: el porcentaje de propina, que es más comparable que la propina absoluta.

Code
# Crear la variable tip_pct (porcentaje de propina)
tips <- tips %>%
  mutate(tip_pct = (tip / total_bill) * 100)

# Ver las primeras filas con la nueva variable
head(tips)
  total_bill  tip    sex smoker day   time size   tip_pct
1      16.99 1.01 Female     No Sun Dinner    2  5.944673
2      10.34 1.66   Male     No Sun Dinner    3 16.054159
3      21.01 3.50   Male     No Sun Dinner    3 16.658734
4      23.68 3.31   Male     No Sun Dinner    2 13.978041
5      24.59 3.61 Female     No Sun Dinner    4 14.680765
6      25.29 4.71   Male     No Sun Dinner    4 18.623962

Construyendo la visualización final, capa por capa

Queremos visualizar cómo la tip_pct se relaciona con la total_bill. Un diagrama de dispersión es ideal para esto. Pero queremos añadir la información sobre si el cliente es fumador y el día de la semana.

Capa 1: La base - Datos, estéticas y geometría

Comenzamos con lo más básico: un diagrama de dispersión de total_bill vs. tip_pct.

Code
# Capa base
ggplot(data = tips, mapping = aes(x = total_bill, y = tip_pct)) +
  geom_point()

Esto ya nos da una primera idea. Parece que, en contra de la intuición, el porcentaje de propina tiende a disminuir ligeramente a medida que la factura total aumenta. Hay mucha dispersión, así que necesitamos más información.

Capa 2: Añadiendo color y transparencia

Vamos a usar el color para distinguir entre fumadores y no fumadores. También añadiremos algo de transparencia (alpha) para gestionar los puntos que se superponen.

Code
ggplot(data = tips, mapping = aes(x = total_bill, y = tip_pct, color = smoker)) +
  # Añadimos alpha FUERA de aes() porque queremos que sea un valor fijo
  geom_point(alpha = 0.7)

Interesante. No parece haber una diferencia abrumadora entre fumadores y no fumadores, aunque los puntos azules (no fumadores) parecen estar un poco más agrupados.

Capa 3: Añadiendo una línea de tendencia (geom_smooth)

Un diagrama de dispersión puede ser ruidoso. Añadir una línea de tendencia nos ayuda a ver el patrón principal. ggplot2 lo hace increíblemente fácil con geom_smooth().

Code
ggplot(data = tips, mapping = aes(x = total_bill, y = tip_pct, color = smoker)) +
  geom_point(alpha = 0.7) +
  # Añadimos una línea de tendencia lineal (method = "lm")
  geom_smooth(method = "lm", se = FALSE) # se=FALSE quita el intervalo de confianza
`geom_smooth()` using formula = 'y ~ x'

Ahora la tendencia es mucho más clara. Ambas líneas tienen una pendiente negativa. La línea de los fumadores (roja) parece estar ligeramente por encima de la de los no fumadores, ¿quizás los fumadores dejan un porcentaje de propina un poco mayor en facturas pequeñas?

Capa 4: ¡Divide y vencerás con facetas!

El gráfico se está volviendo complejo. Queremos añadir una dimensión más: el día de la semana (day). Si añadimos esto como otra estética (ej. shape), el gráfico se volverá ilegible. ¡Es el momento perfecto para usar facetas!

Usaremos facet_wrap() para crear un subgráfico para cada día de la semana.

Code
ggplot(data = tips, mapping = aes(x = total_bill, y = tip_pct, color = smoker)) +
  geom_point(alpha = 0.7) +
  geom_smooth(method = "lm", se = FALSE) +
  facet_wrap(~ day, ncol = 4) # Faceteamos por día
`geom_smooth()` using formula = 'y ~ x'

Nuestro gráfico casi final, combinando geometrías, estéticas y facetas.

¡Ahora sí! Esta visualización nos cuenta una historia mucho más rica y matizada:

  • La tendencia general de que el porcentaje de propina baja con facturas más altas se mantiene en todos los días.
  • El viernes (Fri) es el día con mayor dispersión y algunas de las propinas porcentuales más altas.
  • El sábado (Sat) y el domingo (Sun) son los días con más datos y patrones más estables.
  • La diferencia entre fumadores y no fumadores parece variar según el día.

Capa 5: El pulido final - Títulos, etiquetas y tema

Nuestro gráfico ya es analíticamente potente, pero no está listo para ser presentado. Le falta contexto. Vamos a usar labs() y theme() para darle el toque final de profesionalidad.

Code
ggplot(data = tips, mapping = aes(x = total_bill, y = tip_pct, color = smoker)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "lm", se = FALSE, linewidth = 1.2) +
  facet_wrap(~ day, ncol = 4) +
  
  # Añadimos las etiquetas y títulos
  labs(
    title = "El Porcentaje de Propina Disminuye a Medida que Aumenta la Factura",
    subtitle = "Análisis de la relación entre la factura total y el porcentaje de propina, segmentado por día y si el cliente es fumador.",
    caption = "Fuente de datos: dataset 'tips' (Bryant & Smith, 1995)",
    x = "Factura Total ($)",
    y = "Porcentaje de Propina (%)",
    color = "Cliente Fumador"
  ) +
  
  # Aplicamos un tema limpio y ajustamos la leyenda
  theme_minimal() +
  theme(legend.position = "bottom")
`geom_smooth()` using formula = 'y ~ x'

La visualización final: informativa, clara y estéticamente cuidada.

Guardando tu trabajo: ggsave()

Has creado una visualización fantástica. Ahora, ¿cómo la sacas de R para usarla en un informe o una presentación? La función ggsave() es tu mejor amiga. Guarda el último gráfico que hayas mostrado en un fichero, con un control total sobre el tamaño y la calidad.

# Guardar el último gráfico como un fichero PNG de alta calidad
# ggsave("analisis_propinas.png", width = 10, height = 6, dpi = 300)

Conclusión y próximos pasos

¡Lo has conseguido! Has recorrido todo el camino, desde un lienzo en blanco hasta una visualización de datos compleja, informativa y estéticamente cuidada. A lo largo de esta serie, has adquirido una base sólida en la Gramática de los Gráficos que te permitirá crear casi cualquier visualización estática que puedas imaginar.

El mundo de ggplot2 es vasto y emocionante. A partir de aquí, te animo a explorar por tu cuenta. Aquí tienes algunas ideas para tus próximos pasos:

  • Extensiones de ggplot2: Hay cientos de paquetes que extienden la funcionalidad de ggplot2. Algunos de los más populares son:
    • ggrepel: para etiquetas de texto que no se solapan.
    • patchwork: para combinar múltiples ggplots en una sola figura.
    • gganimate: para crear animaciones con la gramática de ggplot2.
  • Libros y recursos: El libro “ggplot2: Elegant Graphics for Data Analysis” de Hadley Wickham es la biblia definitiva.
  • ¡Practica, practica, practica! Coge cualquier conjunto de datos que te interese y hazte preguntas. Intenta responderlas creando visualizaciones. Es la mejor manera de aprender.

Gracias por acompañarnos en esta serie. ¡Feliz visualización!


Este post es parte de la serie “Iniciación a ggplot2: Guía para crear visualizaciones en R”.