Estadística descriptiva sin sorpresas
summary() se queda corto. Tendencia central (media, mediana, moda), dispersión (varianza, SD, IQR), cuartiles y herramientas mejores como skimr.
Por qué summary() se queda corto
R base tiene una función mágica: summary(). Le pasas un data frame y devuelve un mini-resumen por columna:
summary(mtcars)
#> mpg cyl disp hp
#> Min. :10.40 Min. :4.000 Min. : 71.1 Min. : 52.0
#> 1st Qu.:15.43 1st Qu.:4.000 1st Qu.:120.8 1st Qu.: 96.5
#> Median :19.20 Median :6.000 Median :196.3 Median :123.0
#> Mean :20.09 Mean :6.188 Mean :230.7 Mean :146.7
#> 3rd Qu.:22.80 3rd Qu.:8.000 3rd Qu.:326.0 3rd Qu.:180.0
#> Max. :33.90 Max. :8.000 Max. :400.0 Max. :335.0Útil. Pero deja preguntas sin responder:
- ¿Cuántos
NAtiene cada columna? - ¿Cuál es la desviación estándar? ¿La asimetría?
- ¿Cómo se ve la distribución de un vistazo?
- ¿Qué pasa con variables categóricas? (
summary()solo cuenta frecuencias si la columna es factor.)
Para análisis serio, hay que ir más allá. Veamos cómo.
Tendencia central: tres medidas, tres usos
Hay tres formas básicas de resumir “el centro” de una distribución:
- Media (
mean(x, na.rm = TRUE)), promedio aritmético. Sensible a outliers. - Mediana (
median(x, na.rm = TRUE)), valor que divide a la mitad. Robusta a outliers. - Moda: valor más frecuente. R base no tiene función. Hay que hacerlo a mano.
¿Cuándo cada una?
| Tipo de datos | Medida central |
|---|---|
| Numérico simétrico sin outliers | Media |
| Numérico con cola larga (precios, ingresos, tiempos) | Mediana |
| Ordinal (rating 1-5) | Mediana |
| Categórico nominal | Moda |
Ejemplo concreto: salarios de una empresa. La media puede ser 50.000 € pero la mediana 35.000 €. Si el CEO gana 5 M, la media miente sobre lo que cobra “el empleado típico”. Reporta mediana.
Una moda casera en R:
moda <- function(x) {
ux <- unique(na.omit(x))
ux[which.max(tabulate(match(x, ux)))]
}
moda(mtcars$cyl) # 8Dispersión: qué tan “extendido” está
Tres medidas habituales:
- Varianza (
var(x)), promedio de las desviaciones al cuadrado. - Desviación estándar (
sd(x)), raíz cuadrada de la varianza, en unidades originales. - IQR (
IQR(x)), rango intercuartílico: Q3 − Q1. Robusto a outliers.
La SD es la métrica por defecto en datos aproximadamente simétricos. El IQR es la métrica por defecto en distribuciones asimétricas o con outliers, viaja con la mediana.
mean(mtcars$mpg) # 20.09
sd(mtcars$mpg) # 6.03
median(mtcars$mpg) # 19.2
IQR(mtcars$mpg) # 7.375Pareja sana: (mediana, IQR) o (media, SD). Mezclar media + IQR es raro y confunde.
Cuartiles y percentiles
quantile(mtcars$mpg)
#> 0% 25% 50% 75% 100%
#> 10.40 15.43 19.20 22.80 33.90Cuartiles por defecto (0 %, 25 %, 50 %, 75 %, 100 %). Para otros percentiles:
quantile(mtcars$mpg, probs = c(0.1, 0.5, 0.9))
#> 10% 50% 90%
#> 14.34 19.20 30.09Útil para reportes que dicen “el 90 % de las observaciones está por debajo de X”.
skimr: el resumen completo
install.packages("skimr")
library(skimr)
skim(mtcars)Salida (resumida):
── Variable type: numeric ─────────────────────────────────
skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
1 mpg 0 1 20.1 6.03 10.4 15.4 19.2 22.8 33.9 ▃▇▅▁▂
2 cyl 0 1 6.19 1.79 4 4 6 8 8 ▆▁▃▁▇
3 disp 0 1 231. 124. 71.1 121. 196. 326. 400 ▇▃▃▃▆
Información que summary() no daba:
n_missing: cuántosNApor columna.complete_rate: proporción no-NA.sd: desviación estándar.hist: sparkline ASCII de la distribución. Detectas asimetría, bimodalidad y outliers de un vistazo.
skim() debería ser tu primer comando al recibir un dataset nuevo. Sustituye al reflejo de summary().
Resumen por grupos con dplyr
Cuando quieres ver descriptivas por grupo (lo más común en análisis):
library(dplyr)
mtcars |>
group_by(cyl) |>
summarise(
n = n(),
mpg_media = mean(mpg, na.rm = TRUE),
mpg_sd = sd(mpg, na.rm = TRUE),
mpg_mediana = median(mpg, na.rm = TRUE),
mpg_iqr = IQR(mpg, na.rm = TRUE),
.groups = "drop"
)Es el patrón split-apply-combine del tutorial de group_by aplicado a estadística descriptiva.
Trampas habituales
- Reportar media en datos con outliers o sesgo. La media de ingresos es casi siempre inflada por unos pocos altos. La mediana suele ser la respuesta correcta a “¿cuánto gana el empleado típico?”.
- Olvidar
na.rm = TRUE. Si tu columna tiene un soloNA,mean(x)devuelveNA. Todas las funciones (mean,sd,median, etc.) aceptanna.rm = TRUE. Decisión consciente, no automática. - Reportar SD con mediana. La SD asume simetría. La mediana se usa porque no la hay. Reportar ambas juntas confunde. Usa mediana + IQR o media + SD, no las mezcles.
summary()sin pensar. Útil para inspección rápida, pero no es un análisis descriptivo completo. Acostúmbrate askim()para datasets nuevos.
En la siguiente entrega
Has aprendido a resumir datos. La siguiente pieza es entender qué asume un test estadístico sobre la distribución de tus datos. La mayoría de tests clásicos asumen normalidad. Aprender cuándo se cumple y qué hacer cuando no es el siguiente paso. Lo siguiente.