Facetado: facet_wrap y facet_grid

r
visualizacion
ggplot2
Small multiples como herramienta de exploración. Diferencia entre facet_wrap y facet_grid, cuándo usar scales = ‘free’ (y cuándo no), control de layout y labelling.

¿Qué son los small multiples?

Edward Tufte llamó small multiples al patrón de mostrar el mismo gráfico repetido para distintos subgrupos, alineados, con escalas comparables. Es una de las herramientas más potentes para detectar patrones que en un solo gráfico saturan o se ocultan.

En ggplot2 esto se hace con dos funciones: facet_wrap y facet_grid. La diferencia es sutil pero crítica.

facet_wrap: una variable

facet_wrap divide el gráfico en paneles según una variable categórica y los acomoda en una cuadrícula automática:

library(ggplot2)
library(palmerpenguins)

ggplot(penguins, aes(bill_length_mm, flipper_length_mm)) +
  geom_point() +
  facet_wrap(~ species)

Resultado: tres paneles (uno por especie) en una fila o dos según el tamaño del dispositivo.

La fórmula ~ variable significa “facetar por esta variable”. La tilde es obligatoria, es notación de fórmula heredada de R clásico.

Layout: nrow, ncol, dir

Por defecto ggplot2 elige el layout. Para controlarlo:

facet_wrap(~ species, nrow = 1)     # los tres en una fila
facet_wrap(~ species, ncol = 2)     # 2 columnas (con la tercera abajo)
facet_wrap(~ species, dir = "v")    # rellena por columnas en vez de por filas

Para presentación, casi siempre conviene fijar el layout explícitamente, el “automático” depende del tamaño de salida y puede sorprenderte al exportar.

facet_grid: dos variables cruzadas

facet_grid cruza dos variables: una para filas, otra para columnas:

ggplot(penguins, aes(bill_length_mm, flipper_length_mm)) +
  geom_point() +
  facet_grid(island ~ species)

Resultado: una cuadrícula con island (3 islas) en filas y species (3 especies) en columnas. Las combinaciones inexistentes (especies que no viven en ciertas islas) aparecen como paneles vacíos.

La notación filas ~ columnas es la convención. Si solo quieres facetar por columnas:

facet_grid(. ~ species)

Y solo por filas:

facet_grid(species ~ .)

El . significa “nada en este eje”.

facet_wrap vs facet_grid: cuál elegir

Regla mental simple:

  • Una variablefacet_wrap. Mejor uso del espacio.
  • Dos variables cruzadasfacet_grid. Permite leer la cuadrícula como una tabla pivote visual.

Excepción: si tu única variable tiene muchos niveles (>12), facet_wrap(~ var, ncol = N) da mejor resultado que cualquier otra forma.

scales: cuándo “fixed” y cuándo “free”

Por defecto, todos los paneles comparten los mismos rangos de ejes (scales = "fixed"). Esto es lo que hace de los small multiples una herramienta de comparación: lo que ves grande en un panel ES grande en términos absolutos.

# Default: ejes compartidos
facet_wrap(~ species)

# Equivalente explícito
facet_wrap(~ species, scales = "fixed")

A veces, sin embargo, los grupos tienen rangos muy distintos y querer comparar absolutos esconde la forma local:

facet_wrap(~ species, scales = "free_y")   # cada panel su propio eje Y
facet_wrap(~ species, scales = "free_x")   # eje X libre
facet_wrap(~ species, scales = "free")     # ambos ejes libres

Riesgo crítico: cuando liberas las escalas, dejas de poder comparar entre paneles. Si dos paneles parecen iguales pero uno está en rango 0-10 y el otro en 0-1000, has comunicado información que no existe.

Regla mental: scales = "free" es para explorar formas dentro de cada grupo, no para presentar comparaciones. Para presentación, casi siempre "fixed".

labeller: etiquetas legibles

Por defecto las etiquetas de los paneles son los valores literales de la variable. Si esos valores son códigos crípticos ("sp1", "sp2"), conviene mapearlos a algo legible:

facet_wrap(
  ~ species,
  labeller = labeller(species = c(
    "Adelie"    = "Pingüino de Adelia",
    "Chinstrap" = "Pingüino barbijo",
    "Gentoo"    = "Pingüino papúa"
  ))
)

Para incluir el nombre de la variable en la etiqueta:

facet_wrap(~ species, labeller = label_both)
# Resultado: "species: Adelie", etc.

Trampas habituales

  • scales = "free" por reflejo. Lo activas porque “queda más bonito” y has perdido la comparabilidad que era el punto entero del facetado. Si vas a ponerlo, justifícalo en prosa al lado del gráfico.
  • Olvidar la tilde en la fórmula. facet_wrap(species) da error. Tiene que ser facet_wrap(~ species). La tilde no es decoración.
  • Demasiados paneles. Más de 12-16 paneles produce small multiples que son simplemente small y dejan de ser informativos. Si tienes 50 niveles, hay un problema de modelado anterior, agrupa, top-N, o usa otro gráfico.
  • facet_grid con dos variables independientes. Si tus dos variables no tienen una relación natural, los paneles vacíos confunden. Conviene facet_wrap(~ interaction(a, b)) o reorganizar los datos antes.

En la siguiente entrega

Has aprendido a multiplicar gráficos por grupos. La siguiente pieza son las escalas: cómo controlar la traducción entre valores de los datos y propiedades visuales, ejes logarítmicos, fechas, percentiles, formatos numéricos. Es el componente número 4 de la gramática y lo que separa un gráfico bruto de uno pulido. Lo siguiente.