Cómo leer un diagrama de caja
Un diagrama de caja comprime toda una distribución en cinco números y los dibuja como un único glifo compacto. Aprender a leerlo toma treinta segundos, así que hagámoslo primero; cada pieza tiene un significado preciso:
- La línea gruesa dentro de la caja es la mediana: la mitad de los datos queda por debajo, la otra mitad por encima.
- La caja en sí abarca el rango intercuartílico (IQR): del primer cuartil (25% de los datos por debajo) al tercer cuartil (75% por debajo). La mitad central de tus datos vive dentro de la caja.
- Los bigotes son las líneas que salen de la caja. Cada uno llega hasta el punto más extremo que aún esté dentro de 1.5 × IQR desde el borde de la caja, de modo que cubren "el rango ordinario" de los datos, no el rango completo.
- Los puntos individuales más allá de los bigotes son valores a más de 1.5 × IQR de la caja: marcados como atípicos sospechosos, dibujados uno a uno para que puedas contarlos.
Una caja alta significa datos dispersos; una línea de mediana descentrada dentro de la caja significa asimetría; un reguero de puntos más allá de un bigote significa una cola pesada en ese lado. Un histograma muestra la misma distribución con más detalle, pero el superpoder del diagrama de caja es que una docena de ellos caben lado a lado, lo que lo convierte en el gráfico para comparar grupos.
Un boxplot de una variable
La función es boxplot(), y para un solo vector numérico es una llamada:
scores <- c(52, 55, 58, 60, 61, 63, 64, 66, 68, 70, 72, 95)
boxplot(scores,
main = "Test scores",
ylab = "Score")
La imagen que dibuja: una caja de 59 a 69 con la línea de la mediana en 63.5, bigotes que bajan hasta 52 y suben hasta 72, y un punto solitario flotando en 95: el atípico que un resumen de media y desviación estándar habría absorbido en silencio. Ese "un valor no es como los demás" instantáneo es para lo que sirven los diagramas de caja.
(Como en todas las páginas de este capítulo, las llamadas de graficado son fragmentos estáticos: el ejecutor de abajo solo muestra salida de texto. Ejecútalas en local para ver el dibujo.)
Comparar grupos: la interfaz de fórmula
El uso cotidiano real es una caja por grupo, y para eso boxplot() acepta una fórmula: y ~ group, que se lee "y desglosada por grupo". El dataset integrado de R ToothGrowth —la longitud dental de 60 cobayas que recibieron vitamina C mediante zumo de naranja (OJ) o ácido ascórbico (VC)— es la demostración clásica:
boxplot(len ~ supp,
data = ToothGrowth,
main = "Tooth growth by supplement",
xlab = "Supplement",
ylab = "Tooth length")
Aparecen dos cajas sobre una escala vertical compartida: la caja de OJ queda notablemente más arriba que la de VC, con su mediana en torno a 22 frente a unos 19. Como ambas cajas comparten un mismo eje, la comparación es honesta por construcción: no hay riesgo de que dos gráficos con escalas distintas favorezcan a un grupo. La columna de agrupación debe ser un factor (o un vector de caracteres); cada nivel se convierte en una caja.
Las fórmulas también se anidan: boxplot(len ~ supp * dose, data = ToothGrowth) dibuja seis cajas, una por cada combinación de suplemento y dosis. Cuando una diferencia entre grupos parece real en las cajas, la siguiente pregunta natural —¿es algo más que ruido?— es la que responde una prueba t.
Etiquetas, colores y boxplots horizontales
Los argumentos de estilo siguen las convenciones del graficado base. names etiqueta las cajas, col las rellena; pasa un vector para colorear cada grupo de forma distinta:
boxplot(len ~ supp,
data = ToothGrowth,
names = c("Orange juice", "Ascorbic acid"),
col = c("orange", "lightblue"),
main = "Tooth growth by supplement",
ylab = "Tooth length")
Dos interruptores más que se ganan el puesto:
horizontal = TRUErota todo el gráfico para que las cajas corran a lo largo del eje horizontal. Hazlo siempre que los nombres de los grupos sean largos: las etiquetas horizontales siguen siendo legibles donde las verticales chocan.notch = TRUEtalla una muesca alrededor de cada mediana; cuando las muescas de dos grupos no se solapan, sus medianas plausiblemente difieren. Trátalo como una pista visual, no como una prueba.
Los números detrás de la caja
Todo lo que el gráfico dibuja sale de números que puedes imprimir. quantile() da el resumen de cinco números, y boxplot.stats() te da exactamente lo que el gráfico usa, incluidos los atípicos. Este sí puedes ejecutarlo aquí mismo:
Ojo: son primos, no gemelos: quantile() informa el mínimo y el máximo verdaderos, mientras que s$stats termina en los bigotes, los puntos más extremos dentro de la cerca de 1.5 × IQR. La diferencia entre ambos es precisamente s$out, aquí el solitario 95. Cuando alguien pregunta "¿qué filas son esos puntos atípicos?", x[x %in% boxplot.stats(x)$out] —o un filtro sobre los valores de la cerca— lo responde.
Boxplots con ggplot2
En ggplot2 la agrupación va en el mapeo estético en lugar de en una fórmula:
library(ggplot2)
ggplot(ToothGrowth, aes(x = supp, y = len, fill = supp)) +
geom_boxplot() +
labs(title = "Tooth growth by supplement",
x = "Supplement", y = "Tooth length")
Las mismas dos cajas, con leyenda y tema de regalo. La versión de ggplot2 escala mejor cuando el gráfico crece: faceta por dose, superpón los puntos brutos con geom_jitter(width = 0.1), y el código sigue siendo declarativo. Para una comparación puntual durante un análisis, boxplot(y ~ g, data = df) sigue siendo lo más rápido que puedes teclear.
Lo que te llevas
- Anatomía de la caja: línea de la mediana, caja = IQR, bigotes = puntos más extremos dentro de 1.5 × IQR, puntos más allá = atípicos sospechosos.
boxplot(x)para una variable;boxplot(y ~ group, data = df)para comparar grupos lado a lado sobre una escala compartida y honesta.- Da estilo con
names, un vectorcolpor grupo yhorizontal = TRUEcuando las etiquetas son largas. boxplot.stats(x)$statsy$outson el gráfico convertido en números: úsalos para extraer los atípicos que el gráfico señala.- ggplot2:
geom_boxplot()con el grupo mapeado axofill.
Lo siguiente: el gráfico de dispersión, de la distribución de una variable a la relación entre dos.
Preguntas frecuentes
¿Cómo se hace un boxplot en R?
Llama a boxplot(x) sobre un vector numérico para una sola caja, o usa la interfaz de fórmula boxplot(y ~ group, data = df) para obtener una caja por grupo, lado a lado. Ambas vienen con R base: no hacen falta paquetes.
¿Qué significan las partes de un diagrama de caja?
La línea gruesa dentro de la caja es la mediana. La caja abarca el rango intercuartílico, del primer cuartil al tercero. Los bigotes llegan hasta los puntos más extremos que estén dentro de 1.5 veces el IQR desde la caja, y todo lo que queda más allá de los bigotes se dibuja como un punto individual: un valor atípico sospechoso.
¿Cómo se hace un boxplot por grupo en R?
Usa una fórmula: boxplot(len ~ supp, data = ToothGrowth) dibuja una caja por cada nivel de supp. La variable de agrupación debe ser una columna de tipo factor o carácter; cada nivel se convierte en una caja sobre una escala compartida.
¿Cómo se obtienen los valores atípicos que muestra un boxplot?
boxplot.stats(x)$out devuelve exactamente los valores que el gráfico dibujaría como puntos más allá de los bigotes, y boxplot.stats(x)$stats da los cinco números detrás de la caja: extremos de los bigotes, bisagras y mediana.