Objetivos de aprendizaje

Al finalizar el tema, el estudiante será capaz de:

  • Organizar datos cualitativos y cuantitativos en tablas de distribución de frecuencias.
  • Calcular e interpretar medidas de tendencia central, posición, dispersión y forma.
  • Representar cada variable con el gráfico adecuado según su tipo y objetivo.
  • Reproducir análisis descriptivos completos con R, tidyverse y R Markdown.

Datos de trabajo

  • palmerpenguins: 344 pingüinos de 3 especies y 3 islas del archipiélago Palmer.
  • mtcars: 32 automóviles (Motor Trend, 1974): rendimiento, peso, potencia, transmisión.
glimpse(penguins)       # estructura: 344 filas, 8 columnas
## Rows: 344
## Columns: 8
## $ species           <fct> Adelie, Adelie, Adelie, Adelie, Adelie, Adelie, Adel…
## $ island            <fct> Torgersen, Torgersen, Torgersen, Torgersen, Torgerse…
## $ bill_length_mm    <dbl> 39.1, 39.5, 40.3, NA, 36.7, 39.3, 38.9, 39.2, 34.1, …
## $ bill_depth_mm     <dbl> 18.7, 17.4, 18.0, NA, 19.3, 20.6, 17.8, 19.6, 18.1, …
## $ flipper_length_mm <int> 181, 186, 195, NA, 193, 190, 181, 195, 193, 190, 186…
## $ body_mass_g       <int> 3750, 3800, 3250, NA, 3450, 3650, 3625, 4675, 3475, …
## $ sex               <fct> male, female, female, NA, female, male, female, male…
## $ year              <int> 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007…

penguins contiene valores perdidos (NA): se aprovecha para mostrar drop_na().

1.1 Organización de los datos: distribución de frecuencias

Distribución de frecuencias: conceptos

  • Frecuencia absoluta (\(n_i\)): número de observaciones en la clase \(i\).
  • Frecuencia relativa (\(h_i\)): proporción del total.
  • Acumuladas (\(N_i\), \(H_i\)): suman las clases hasta la \(i\)-ésima; solo tienen sentido con categorías ordenadas.

\[h_i = \frac{n_i}{n} \qquad N_i = \sum_{j=1}^{i} n_j \qquad H_i = \frac{N_i}{n} \qquad \sum h_i = 1\]

¿Tiene sentido acumular frecuencias de la variable isla? No: es nominal.

Código R: variable cualitativa

# Frecuencias de la especie con dplyr
frec_especie <- penguins |>
  count(species, name = "n_i") |>
  mutate(h_i = n_i / sum(n_i),   # relativa
         N_i = cumsum(n_i),      # absoluta acumulada
         H_i = cumsum(h_i))      # relativa acumulada
tabla(frec_especie)
species n_i h_i N_i H_i
Adelie 152 0.442 152 0.442
Chinstrap 68 0.198 220 0.640
Gentoo 124 0.360 344 1.000

Alternativa con janitor

penguins |> tabyl(species) |>
  adorn_totals("row") |> adorn_pct_formatting(digits = 1) |> tabla()
species n percent
Adelie 152 44.2%
Chinstrap 68 19.8%
Gentoo 124 36.0%
Total 344 100.0%

Interpretación: especies

Adelie es la especie más frecuente (44.2 %); Chinstrap, la menos representada (19.8 %). Al ser nominal, \(N_i\) y \(H_i\) no se interpretan.

Variables cuantitativas: intervalos de clase

  • Número de clases (Sturges): \(k = \lceil 1 + \log_2 n \rceil\).
  • Amplitud: \(A = \lceil R / k \rceil\), con \(R = x_{máx} - x_{mín}\).
  • Marca de clase: \(x_i = (L_i + L_s)/2\).
  • Intervalos cerrados por la izquierda \([L_i; L_s)\).

Sturges es una convención. Mencionar Scott y Freedman-Diaconis (nclass.FD()).

Código R: tabla agrupada con cut()

masa <- penguins |> drop_na(body_mass_g) |> pull(body_mass_g)
k <- nclass.Sturges(masa)               # regla de Sturges: 10
A <- ceiling(diff(range(masa)) / k)     # amplitud: 360 g
cortes <- seq(min(masa), by = A, length.out = k + 1)
frec_masa <- tibble(masa) |>
  mutate(clase = cut(masa, breaks = cortes, right = FALSE,
                     include.lowest = TRUE, dig.lab = 4)) |>
  count(clase, name = "n_i") |>
  mutate(x_i = head(cortes, -1) + A / 2,  # marca de clase
         h_i = n_i / sum(n_i), H_i = cumsum(h_i))

Interpretación: masa agrupada

tabla(frec_masa |> relocate(x_i, .after = clase))
clase x_i n_i h_i H_i
[2700,3060) 2 880 15 0.044 0.044
[3060,3420) 3 240 43 0.126 0.170
[3420,3780) 3 600 71 0.208 0.377
[3780,4140) 3 960 53 0.155 0.532
[4140,4500) 4 320 42 0.123 0.655
[4500,4860) 4 680 41 0.120 0.775
[4860,5220) 5 040 28 0.082 0.857
[5220,5580) 5 400 27 0.079 0.936
[5580,5940) 5 760 16 0.047 0.982
[5940,6300] 6 120 6 0.018 1.000

La clase modal es [3420,3780) con 71 pingüinos; el 53.2 % pesa menos de 4 140 g.

1.2 Medidas de tendencia central, no central, de dispersión y de forma

Medidas de tendencia central y de posición

  • Media: \(\bar{x} = \sum x_i / n\); sensible a valores extremos.
  • Mediana (Me): valor central; robusta.
  • Moda (Mo): valor más frecuente; válida para nominales.
  • Cuartiles y percentiles: \(Q_1 = P_{25}\), \(Me = Q_2 = P_{50}\), \(Q_3 = P_{75}\).

R usa quantile(type = 7) por defecto; SPSS y Minitab usan el tipo 6 (Hyndman y Fan, 1996).

Código R: tendencia central y posición

# R no tiene función para la moda estadística: se define una
moda <- function(x) { t <- table(x); names(t)[t == max(t)] }
centro <- penguins |>
  drop_na(flipper_length_mm) |>
  group_by(species) |>
  summarise(media = mean(flipper_length_mm),
            mediana = median(flipper_length_mm),
            Q1 = quantile(flipper_length_mm, 0.25),
            Q3 = quantile(flipper_length_mm, 0.75),
            P90 = quantile(flipper_length_mm, 0.90))
tabla(centro, digits = 1)
species media mediana Q1 Q3 P90
Adelie 190.0 190 186 195 198
Chinstrap 195.8 196 191 201 205
Gentoo 217.2 216 212 221 228
moda(penguins$flipper_length_mm)   # moda global
## [1] "190"

Interpretación: longitud de aleta

  • En las tres especies \(\bar{x} \approx Me\): distribuciones aproximadamente simétricas.
  • Gentoo supera a Adelie en 27.2 mm en promedio.
  • El \(P_{90}\) de Adelie (198 mm) es menor que el \(Q_1\) de Gentoo (212 mm).

Medidas de dispersión

\[s^2 = \frac{\sum (x_i - \bar{x})^2}{n - 1} \qquad s = \sqrt{s^2} \qquad RIC = Q_3 - Q_1 \qquad CV = \frac{s}{\bar{x}} \cdot 100\,\%\]

var() y sd() usan n − 1 (estimador insesgado).

Código R: dispersión por grupo

dispersion <- penguins |>
  drop_na(body_mass_g) |>
  group_by(species) |>
  summarise(rango    = diff(range(body_mass_g)),
            varianza = var(body_mass_g),
            de       = sd(body_mass_g),
            RIC      = IQR(body_mass_g),
            CV       = de / mean(body_mass_g) * 100)
tabla(dispersion, digits = 1)
species rango varianza de RIC CV
Adelie 1 925 210 283 458.6 650.0 12.4
Chinstrap 2 100 147 714 384.3 462.5 10.3
Gentoo 2 350 254 133 504.1 800.0 9.9

Interpretación: dispersión

  • En términos absolutos, Gentoo es la más dispersa (s = 504.1 g).
  • En términos relativos, Gentoo es la más homogénea (CV = 9.9 %).
  • Para comparar grupos con medias distintas, use el CV.

Medidas de forma

  • Asimetría: \(g_1 = m_3 / m_2^{3/2}\) (\(g_1 > 0\): cola a la derecha).
  • Curtosis: \(\beta_2 = m_4 / m_2^2\) (normal: \(\beta_2 = 3\)), con \(m_r = \sum (x_i - \bar{x})^r / n\).
  • moments::kurtosis() reporta \(\beta_2\); psych::describe() reporta el exceso \(\beta_2 - 3\).

Código R: forma y resúmenes rápidos

forma <- mtcars |>
  summarise(across(c(mpg, hp, wt),
                   list(media = mean, mediana = median,
                        g1 = skewness, b2 = kurtosis))) |>
  pivot_longer(everything(), names_to = c("variable", ".value"),
               names_sep = "_")
tabla(forma)
variable media mediana g1 b2
mpg 20.091 19.200 0.640 2.799
hp 146.688 123.000 0.761 3.052
wt 3.217 3.325 0.444 3.172

Resúmenes con psych y skimr

describe(mtcars[, c("mpg", "hp", "wt")])   # psych: curtosis en exceso
vars n mean sd median trimmed mad min max range skew kurtosis se
mpg 1 32 20.091 6.0269 19.200 19.696 5.4115 10.400 33.900 23.500 0.6107 -0.3728 1.065
hp 2 32 146.688 68.5629 123.000 141.192 77.0952 52.000 335.000 283.000 0.7260 -0.1356 12.120
wt 3 32 3.217 0.9785 3.325 3.153 0.7672 1.513 5.424 3.911 0.4231 -0.0227 0.173
skim(mtcars, mpg, hp, wt)                  # skimr
Data summary
Name mtcars
Number of rows 32
Number of columns 11
_______________________
Column type frequency:
numeric 3
________________________
Group variables None

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
mpg 0 1 20.09 6.03 10.40 15.43 19.20 22.80 33.90 ▃▇▅▁▂
hp 0 1 146.69 68.56 52.00 96.50 123.00 180.00 335.00 ▇▇▆▃▁
wt 0 1 3.22 0.98 1.51 2.58 3.33 3.61 5.42 ▃▃▇▁▂

Interpretación: forma de hp

Las tres variables presentan asimetría positiva; en hp, \(\bar{x}\) = 146.7 > Me = 123.

1.3 Gráficos

¿Qué gráfico usar?

Objetivo Tipo de variable Gráfico ggplot2
Ver la distribución Una cuantitativa Histograma / densidad geom_histogram(), geom_density()
Resumir y detectar atípicos Cuantitativa por grupos Diagrama de caja geom_boxplot()
Comparar frecuencias Cualitativa Barras geom_bar(), geom_col()
Explorar una relación Dos cuantitativas Dispersión geom_point()
Comparar con la normal Una cuantitativa QQ-plot stat_qq(), stat_qq_line()

Buenas prácticas de etiquetado

  • Título informativo; ejes con nombre y unidades; fuente en el caption.
  • Escala honesta (barras desde cero); color con propósito; sin decoración innecesaria.

Histograma

ggplot(penguins, aes(x = body_mass_g)) +
  geom_histogram(breaks = cortes, fill = "#7A4FC9", color = "white") +
  labs(title = "Distribución de la masa corporal",
       x = "Masa corporal (g)", y = "Frecuencia absoluta",
       caption = "Fuente: palmerpenguins")

Diagrama de caja

ggplot(penguins, aes(x = species, y = body_mass_g, fill = species)) +
  geom_boxplot(show.legend = FALSE) +
  scale_fill_manual(values = pal) +
  labs(title = "Masa corporal por especie",
       x = "Especie", y = "Masa corporal (g)")

Densidad y barras

g1 <- ggplot(penguins, aes(flipper_length_mm, fill = species)) +
  geom_density(alpha = 0.5) + scale_fill_manual(values = pal) +
  labs(title = "Densidad de la aleta", x = "Longitud de aleta (mm)", y = "Densidad")
g2 <- ggplot(penguins, aes(island, fill = species)) + geom_bar() +
  scale_fill_manual(values = pal) +
  labs(title = "Especie por isla", x = "Isla", y = "Frecuencia")
gridExtra::grid.arrange(g1, g2, ncol = 2)

Dispersión y QQ-plot

g3 <- ggplot(mtcars, aes(wt, mpg)) + geom_point(color = "#7A4FC9") +
  geom_smooth(method = "lm", se = FALSE, color = "#C00000") +
  labs(title = "Peso vs. rendimiento", x = "Peso (1000 lb)", y = "Millas por galón")
g4 <- ggplot(filter(penguins, species == "Adelie"), aes(sample = body_mass_g)) +
  stat_qq(color = "#7A4FC9") + stat_qq_line(color = "#C00000") +
  labs(title = "QQ-plot: masa de Adelie", x = "Cuantiles teóricos", y = "Cuantiles muestrales")
gridExtra::grid.arrange(g3, g4, ncol = 2)

Mini-caso y cierre

Mini-caso: rendimiento en mtcars

count(mtcars, cyl, name = "n_i") |> tabla()
cyl n_i
4 11
6 7
8 14
mtcars |> group_by(cyl) |>
  summarise(media = mean(mpg), mediana = median(mpg),
            de = sd(mpg), CV = de / media * 100) |> tabla(digits = 2)
cyl media mediana de CV
4 26.66 26.0 4.51 16.91
6 19.74 19.7 1.45 7.36
8 15.10 15.2 2.56 16.95

Pregunta: ¿qué medidas y qué gráfico presentarías a un gerente de flota?

Síntesis

  • Las tablas de frecuencias (\(n_i\), \(h_i\), \(N_i\), \(H_i\)) organizan cualquier variable.
  • Media, mediana y moda resumen el centro; cuartiles y percentiles, la posición.
  • \(s\), RIC y CV miden la dispersión; el CV compara grupos con medias distintas.
  • Asimetría y curtosis describen la forma.
  • El tipo de variable determina el gráfico.

Ejercicios propuestos

  1. Tabla de frecuencias de island y sex (incluya NA). ¿Qué proporción no tiene sexo?
  2. Agrupe bill_length_mm con Sturges; identifique la clase modal y \(H_5\).
  3. Compare la dispersión de mpg por cyl con \(s\), RIC y CV.
  4. Con iris, calcule \(g_1\) y \(\beta_2\) de Petal.Length por especie.
  5. Histograma y boxplot de Sepal.Width por especie con buenas prácticas.

Referencias

  • Çetinkaya-Rundel, M., & Hardin, J. (2021). Introduction to modern statistics. OpenIntro.
  • Diez, D., Çetinkaya-Rundel, M., & Barr, C. D. (2019). OpenIntro statistics (4th ed.). OpenIntro.
  • Horst, A. M., Hill, A. P., & Gorman, K. B. (2020). palmerpenguins [R package].
  • Hyndman, R. J., & Fan, Y. (1996). Sample quantiles in statistical packages. The American Statistician, 50(4), 361–365.
  • Ismay, C., & Kim, A. Y. (2020). Statistical inference via data science: A ModernDive into R and the tidyverse. CRC Press.
  • Wickham, H. (2016). ggplot2: Elegant graphics for data analysis (2nd ed.). Springer.
  • Wickham, H., Çetinkaya-Rundel, M., & Grolemund, G. (2023). R for data science (2nd ed.). O’Reilly.
  • Xie, Y., Allaire, J. J., & Grolemund, G. (2018). R Markdown: The definitive guide. CRC Press.