Objetivos de aprendizaje

  • Modelar fenómenos aleatorios con las distribuciones binomial, Poisson, exponencial y normal.
  • Contrastar hipótesis sobre medias, normalidad y asociación, e interpretar el valor p.
  • Comparar medias de tres o más grupos con ANOVA y verificar sus supuestos.
  • Predecir con regresión lineal simple y múltiple, diagnosticando sus supuestos.

2.1 Distribuciones de probabilidad

Variable aleatoria y distribución

  • Discreta: función de masa \(p(x) = P(X = x)\), con \(\sum p(x) = 1\).
  • Continua: función de densidad \(f(x)\), con \(\int f(x)\,dx = 1\) y \(P(X = x) = 0\).
  • Acumulada: \(F(x) = P(X \le x)\); \(P(a < X \le b) = F(b) - F(a)\).

Código R: la familia d-p-q-r

# Ejemplo con X ~ Binomial(n = 10, p = 0.4)
dbinom(3, size = 10, prob = 0.4)        # P(X = 3)
## [1] 0.215
pbinom(3, size = 10, prob = 0.4)        # P(X <= 3)
## [1] 0.3823
pbinom(3, 10, 0.4, lower.tail = FALSE)  # P(X > 3)
## [1] 0.6177
qbinom(0.5, size = 10, prob = 0.4)      # mediana
## [1] 4
set.seed(2026)                          # semilla: reproducibilidad
rbinom(5, size = 10, prob = 0.4)        # 5 valores simulados
## [1] 5 4 2 3 4

Interpretación: masa, densidad y acumulada

2.2 Distribuciones discretas y continuas

Distribución binomial

\[P(X = x) = \binom{n}{x} p^x (1-p)^{n-x}, \quad x = 0, 1, \dots, n \qquad E(X) = np \qquad V(X) = np(1-p)\]

  • Supuestos: dos resultados por ensayo, \(n\) fijo, independencia y \(p\) constante.

Sin reposición y n/N > 5 %: usar la hipergeométrica.

Código R: binomial

p <- mean(mtcars$am)                # proporción de autos manuales
n <- 10
dbinom(4, size = n, prob = p)       # P(X = 4)
## [1] 0.2506
pbinom(4, n, p, lower.tail = FALSE) # P(X >= 5)
## [1] 0.3827
c(media = n * p, varianza = n * p * (1 - p))
##    media varianza 
##    4.062    2.412

Interpretación: autos manuales

tibble(x = 0:n, prob = dbinom(x, n, p)) |>
  ggplot(aes(x, prob, fill = x >= 5)) + geom_col(show.legend = FALSE) +
  scale_fill_manual(values = c("#7A4FC9", "#C00000")) +
  scale_x_continuous(breaks = 0:n) +
  labs(title = sprintf("X ~ Bin(10; %.3f)", p),
       x = "N.º de autos manuales", y = "P(X = x)")

P(X ≥ 5) = 0.383: hay un 38 % de probabilidad de encontrar 5 o más autos manuales en 10.

Distribución de Poisson

\[P(X = x) = \frac{e^{-\lambda}\lambda^x}{x!}, \quad x = 0, 1, 2, \dots \qquad E(X) = V(X) = \lambda\]

Código R: Poisson

# Grandes descubrimientos científicos por año (1860-1959)
lambda <- mean(discoveries)          # lambda estimada
dpois(0, lambda)                     # P(X = 0)
## [1] 0.04505
ppois(4, lambda, lower.tail = FALSE) # P(X >= 5)
## [1] 0.2018
qpois(0.95, lambda)                  # percentil 95
## [1] 6
mean(discoveries == 0)               # proporción observada de X = 0
## [1] 0.09
var(discoveries)                     # comparar con lambda
## [1] 5.081

Interpretación: descubrimientos por año

obs <- tibble(x = as.numeric(discoveries)) |> count(x) |>
  mutate(Observado = n / sum(n))
tibble(x = 0:12) |>
  left_join(obs, by = "x") |>
  mutate(Observado = replace_na(Observado, 0), Poisson = dpois(x, lambda)) |>
  pivot_longer(c(Observado, Poisson), names_to = "fuente", values_to = "prop") |>
  ggplot(aes(x, prop, fill = fuente)) + geom_col(position = "dodge") +
  scale_fill_manual(values = c("#B17DF4", "#3C2A63")) +
  scale_x_continuous(breaks = 0:12) +
  labs(x = "N.º de descubrimientos", y = "Proporción", fill = NULL,
       caption = "Fuente: datasets::discoveries")

La varianza observada (5.08) supera a λ (3.1): sobredispersión moderada.

Distribución exponencial

\[f(t) = \lambda e^{-\lambda t} \qquad F(t) = 1 - e^{-\lambda t}, \quad t \ge 0 \qquad E(T) = 1/\lambda\]

  • Falta de memoria: \(P(T > s + t \mid T > s) = P(T > t)\).
  • En R: rate = λ (no la media).

Código R: exponencial

# Si X ~ Poisson(3.1 por año), el tiempo entre eventos T ~ Exp(3.1)
lambda <- 3.1
1 / lambda                                    # E(T) en años
## [1] 0.3226
pexp(0.25, rate = lambda)                     # P(T <= 3 meses)
## [1] 0.5393
pexp(0.5, rate = lambda, lower.tail = FALSE)  # P(T > 6 meses)
## [1] 0.2122
qexp(0.5, rate = lambda)                      # mediana
## [1] 0.2236
cola <- function(t) pexp(t, lambda, lower.tail = FALSE)
cola(0.75) / cola(0.25)                       # falta de memoria = cola(0.5)
## [1] 0.2122

Interpretación: tiempo entre descubrimientos

tibble(t = seq(0, 1.6, 0.005), f = dexp(t, lambda)) |>
  ggplot(aes(t, f)) + geom_line(color = "#7A4FC9", linewidth = 1) +
  geom_area(data = \(d) filter(d, t >= 0.5), fill = "#C00000", alpha = 0.35) +
  geom_vline(xintercept = 1 / lambda, linetype = "dashed") +
  labs(title = "T ~ Exp(λ = 3.1)", x = "Tiempo (años)", y = "f(t)")

Distribución normal

\[f(x) = \frac{1}{\sigma\sqrt{2\pi}}\, e^{-\frac{(x-\mu)^2}{2\sigma^2}} \qquad Z = \frac{X - \mu}{\sigma} \sim N(0, 1)\]

La notación N(μ, σ²) usa la varianza; R pide sd = σ.

Código R: normal

x <- penguins |> filter(species == "Adelie") |>
  drop_na(body_mass_g) |> pull(body_mass_g)
mu <- mean(x); sigma <- sd(x)
pnorm(4500, mean = mu, sd = sigma, lower.tail = FALSE)  # P(X > 4500)
## [1] 0.04066
pnorm(4000, mu, sigma) - pnorm(3000, mu, sigma)  # P(3000 < X < 4000)
## [1] 0.6798
qnorm(0.95, mu, sigma)                         # percentil 95
## [1] 4455
(4500 - mu) / sigma                            # valor z
## [1] 1.743
mean(x > 4500)                                 # proporción observada
## [1] 0.04636

Interpretación: masa de los Adelie

ggplot(tibble(x), aes(x)) +
  geom_histogram(aes(y = after_stat(density)), bins = 14,
                 fill = "#D9C7F7", color = "white") +
  stat_function(fun = dnorm, args = list(mean = mu, sd = sigma),
                color = "#7A4FC9", linewidth = 1) +
  labs(title = sprintf("N(μ = %.0f; σ = %.0f)", mu, sigma),
       x = "Masa corporal (g)", y = "Densidad", caption = "Fuente: palmerpenguins")

Comparación visual de las cuatro distribuciones

bind_rows(
  expand_grid(par = c(0.2, 0.5, 0.8), x = 0:10) |>
    mutate(y = dbinom(x, 10, par), dist = "Binomial (n = 10)", etiqueta = paste("p =", par)),
  expand_grid(par = c(1, 4, 10), x = 0:20) |>
    mutate(y = dpois(x, par), dist = "Poisson", etiqueta = paste("λ =", par)),
  expand_grid(par = c(0.5, 1, 2), x = seq(0, 5, 0.05)) |>
    mutate(y = dexp(x, par), dist = "Exponencial", etiqueta = paste("λ =", par)),
  expand_grid(par = c(1, 2), x = seq(-6, 6, 0.05)) |>
    mutate(y = dnorm(x, 0, par), dist = "Normal (μ = 0)", etiqueta = paste("σ =", par))
) |>
  ggplot(aes(x, y, color = etiqueta)) + geom_line(linewidth = 0.9) +
  facet_wrap(~ dist, scales = "free") + labs(x = NULL, y = NULL, color = NULL)

2.3 Pruebas de hipótesis

Lógica de una prueba de hipótesis

  1. Plantear \(H_0\) y \(H_1\).
  2. Fijar el nivel de significación \(\alpha\).
  3. Elegir la prueba y verificar supuestos.
  4. Calcular el estadístico y el valor p.
  5. Decidir (si \(p < \alpha\), se rechaza \(H_0\)) y concluir en contexto.

El valor p no es la probabilidad de que H0 sea cierta. No rechazar H0 no prueba que sea verdadera.

¿Qué prueba usar?

Objetivo Paramétrica No paramétrica R
Una media t de una muestra Wilcoxon t.test(x, mu =)
Dos medias independientes t de Welch Mann-Whitney t.test(y ~ g)
Dos medias pareadas t pareada Wilcoxon pareada t.test(x, y, paired = TRUE)
Normalidad — Shapiro-Wilk, Anderson-Darling shapiro.test(), ad.test()
Correlación Pearson Spearman cor.test()
Asociación cualitativa — Chi-cuadrado, Fisher chisq.test(), fisher.test()
Tres o más medias ANOVA Kruskal-Wallis aov(), kruskal.test()

t vs. Wilcoxon: la t es robusta con n ≥ 30 salvo asimetría extrema o atípicos. Wilcoxon compara la ubicación de las distribuciones, no las medias. Ejecutar ambas y comparar.

Prueba t para una media

\[t = \frac{\bar{x} - \mu_0}{s/\sqrt{n}} \sim t_{n-1}\]

# ¿La masa media de los Adelie difiere de 3 800 g?
adelie <- penguins |> filter(species == "Adelie")
t.test(adelie$body_mass_g, mu = 3800,
       alternative = "two.sided", conf.level = 0.95)
## 
##  One Sample t-test
## 
## data:  adelie$body_mass_g
## t = -2.7, df = 150, p-value = 0.009
## alternative hypothesis: true mean is not equal to 3800
## 95 percent confidence interval:
##  3627 3774
## sample estimates:
## mean of x 
##      3701

Alternativas: Wilcoxon e infer

wilcox.test(adelie$body_mass_g, mu = 3800)       # ubicación (mediana)
## 
##  Wilcoxon signed rank test with continuity correction
## 
## data:  adelie$body_mass_g
## V = 3821, p-value = 0.007
## alternative hypothesis: true location is not equal to 3800
adelie |> drop_na(body_mass_g) |>
  infer::t_test(response = body_mass_g, mu = 3800)
statistic t_df p_value alternative estimate lower_ci upper_ci
-2.662 150 0.0086 two.sided 3701 3627 3774

Diferencia de medias

# ¿El rendimiento (mpg) difiere según la transmisión?
mtcars |> group_by(am) |>
  summarise(n = n(), media = mean(mpg), de = sd(mpg)) |> tabla()
am n media de
0 19 17.15 3.834
1 13 24.39 6.167
t.test(mpg ~ am, data = mtcars)            # Welch
## 
##  Welch Two Sample t-test
## 
## data:  mpg by am
## t = -3.8, df = 18, p-value = 0.001
## alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
## 95 percent confidence interval:
##  -11.28  -3.21
## sample estimates:
## mean in group 0 mean in group 1 
##           17.15           24.39

Variantes: t clásica, Mann-Whitney y pareada

t.test(mpg ~ am, data = mtcars, var.equal = TRUE)$p.value  # clásica
## [1] 0.000285
wilcox.test(mpg ~ am, data = mtcars, exact = FALSE)$p.value
## [1] 0.001871
# Pareada: mismo paciente con dos fármacos (datos sleep)
with(sleep, t.test(extra[group == 1], extra[group == 2], paired = TRUE))
## 
##  Paired t-test
## 
## data:  extra[group == 1] and extra[group == 2]
## t = -4.1, df = 9, p-value = 0.003
## alternative hypothesis: true mean difference is not equal to 0
## 95 percent confidence interval:
##  -2.4599 -0.7001
## sample estimates:
## mean difference 
##           -1.58

Gráfico: rendimiento por transmisión

ggplot(mtcars, aes(factor(am, labels = c("Automática", "Manual")), mpg)) +
  geom_boxplot(fill = "#B17DF4") + geom_jitter(width = 0.05) +
  labs(x = "Transmisión", y = "Millas por galón", caption = "Fuente: mtcars")

Pruebas de normalidad

map_dfr(list(mpg = mtcars$mpg, hp = mtcars$hp), \(v) {
  sw <- shapiro.test(v); ad <- ad.test(v)
  tibble(W = sw$statistic, p_SW = sw$p.value, A = ad$statistic, p_AD = ad$p.value)
}, .id = "variable") |> tabla()
variable W p_SW A p_AD
mpg 0.948 0.123 0.580 0.121
hp 0.933 0.049 0.708 0.058

QQ-plots

mtcars |> select(mpg, hp) |> pivot_longer(everything()) |>
  ggplot(aes(sample = value)) + stat_qq(color = "#7A4FC9") +
  stat_qq_line(color = "#C00000") + facet_wrap(~ name, scales = "free") +
  labs(x = "Cuantiles teóricos", y = "Cuantiles muestrales")

Correlación entre variables cuantitativas

cor(mtcars$wt, mtcars$mpg)          # r de Pearson
## [1] -0.8677
cor.test(~ wt + mpg, data = mtcars, method = "pearson")
## 
##  Pearson's product-moment correlation
## 
## data:  wt and mpg
## t = -9.6, df = 30, p-value = 0.0000000001
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.9338 -0.7441
## sample estimates:
##     cor 
## -0.8677
# Spearman: exact = FALSE porque hay empates
cor.test(~ wt + mpg, data = mtcars, method = "spearman", exact = FALSE)
## 
##  Spearman's rank correlation rho
## 
## data:  wt and mpg
## S = 10292, p-value = 0.00000000001
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##     rho 
## -0.8864

Matriz de correlaciones

mtcars |> select(mpg, wt, hp, disp) |> cor() |> round(2) |> tabla(digits = 2)
mpg wt hp disp
mpg 1.00 -0.87 -0.78 -0.85
wt -0.87 1.00 0.66 0.89
hp -0.78 0.66 1.00 0.79
disp -0.85 0.89 0.79 1.00

Asociación entre variables cualitativas

tabla_ct <- table(penguins$species, penguins$island)
tabla_ct
##            
##             Biscoe Dream Torgersen
##   Adelie        44    56        52
##   Chinstrap      0    68         0
##   Gentoo       124     0         0
prueba <- chisq.test(tabla_ct)
prueba
## 
##  Pearson's Chi-squared test
## 
## data:  tabla_ct
## X-squared = 300, df = 4, p-value <0.0000000000000002
round(prueba$expected, 1)          # verificar E >= 5
##            
##             Biscoe Dream Torgersen
##   Adelie      74.2  54.8      23.0
##   Chinstrap   33.2  24.5      10.3
##   Gentoo      60.6  44.7      18.7
fisher.test(table(mtcars$am, mtcars$vs))$p.value
## [1] 0.4727

2.4 Análisis de varianza de un factor

ANOVA de un factor

\[F = \frac{CM_{entre}}{CM_{dentro}} = \frac{SC_{entre}/(k-1)}{SC_{dentro}/(n-k)} \sim F_{k-1,\,n-k}\]

  • Supuestos: independencia, normalidad de residuos y homocedasticidad.

Código R: ANOVA y Tukey

datos <- penguins |> drop_na(flipper_length_mm)
modelo_aov <- aov(flipper_length_mm ~ species, data = datos)
summary(modelo_aov)          # tabla ANOVA
##              Df Sum Sq Mean Sq F value              Pr(>F)    
## species       2  52473   26237     595 <0.0000000000000002 ***
## Residuals   339  14953      44                                
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
TukeyHSD(modelo_aov)         # comparaciones múltiples
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = flipper_length_mm ~ species, data = datos)
## 
## $species
##                   diff    lwr    upr p adj
## Chinstrap-Adelie  5.87  3.587  8.153     0
## Gentoo-Adelie    27.23 25.334 29.132     0
## Gentoo-Chinstrap 21.36 19.001 23.726     0

Tamaño del efecto

ss <- summary(modelo_aov)[[1]][["Sum Sq"]]
eta2 <- ss[1] / sum(ss)      # proporción de variabilidad explicada
eta2
## [1] 0.7782

Verificación de supuestos

f <- flipper_length_mm ~ species       # fórmula reutilizable
shapiro.test(residuals(modelo_aov))    # normalidad
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(modelo_aov)
## W = 0.99, p-value = 0.3
leveneTest(f, data = datos)            # Levene (robusta)
Df F value Pr(>F)
group 2 0.3306 0.7188
339 NA NA
bartlett.test(f, data = datos)         # Bartlett
## 
##  Bartlett test of homogeneity of variances
## 
## data:  flipper_length_mm by species
## Bartlett's K-squared = 0.92, df = 2, p-value = 0.6

Presentar primero los gráficos de residuos y luego las pruebas formales. Independencia: se garantiza con el diseño.

Diagnóstico gráfico y alternativas

par(mfrow = c(1, 2)); plot(modelo_aov, which = 1:2); par(mfrow = c(1, 1))

oneway.test(f, data = datos)$p.value   # ANOVA de Welch
## [1] 0.0000000000000000000000000000000000000000000000000000000000000000000000000000003073
kruskal.test(f, data = datos)$p.value  # Kruskal-Wallis
## [1] 0.000000000000000000000000000000000000000000000000000006648

2.5 Regresión lineal simple y múltiple

Regresión lineal

\[Y = \beta_0 + \beta_1 X_1 + \dots + \beta_p X_p + \varepsilon \qquad R^2 = 1 - \frac{SCE}{SCT}\]

  • Supuestos (LINE + VIF): linealidad, independencia, normalidad, homocedasticidad y no multicolinealidad.

Código R: ajuste

m1 <- lm(mpg ~ wt, data = mtcars)        # regresión simple
m2 <- lm(mpg ~ wt + hp, data = mtcars)   # regresión múltiple
tidy(m2, conf.int = TRUE) |> tabla()
term estimate std.error statistic p.value conf.low conf.high
(Intercept) 37.227 1.599 23.285 0.000 33.957 40.497
wt -3.878 0.633 -6.129 0.000 -5.172 -2.584
hp -0.032 0.009 -3.519 0.001 -0.050 -0.013
glance(m2) |> select(r.squared, adj.r.squared, sigma, statistic, p.value, AIC) |> tabla()
r.squared adj.r.squared sigma statistic p.value AIC
0.827 0.815 2.593 69.21 0 156.7

Comparación de modelos y predicción

anova(m1, m2)                            # ¿hp mejora el modelo?
Res.Df RSS Df Sum of Sq F Pr(>F)
30 278.3 NA NA NA NA
29 195.0 1 83.27 12.38 0.0015
predict(m2, newdata = data.frame(wt = 3, hp = 150), interval = "prediction")
##     fit   lwr   upr
## 1 20.83 15.43 26.22

Diagnóstico de supuestos

shapiro.test(residuals(m2))      # normalidad
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(m2)
## W = 0.93, p-value = 0.03
bptest(m2)                       # homocedasticidad (Breusch-Pagan)
## 
##  studentized Breusch-Pagan test
## 
## data:  m2
## BP = 0.88, df = 2, p-value = 0.6
dwtest(m2)                       # independencia (Durbin-Watson)
## 
##  Durbin-Watson test
## 
## data:  m2
## DW = 1.4, p-value = 0.02
## alternative hypothesis: true autocorrelation is greater than 0
vif(m2)                          # multicolinealidad
##    wt    hp 
## 1.767 1.767

Gráficos de diagnóstico

par(mfrow = c(2, 2)); plot(m2); par(mfrow = c(1, 1))

Hay curvatura en residuos vs. ajustados: proponer lm(log(mpg) ~ wt + hp). El orden de filas de mtcars es arbitrario: Durbin-Watson no es interpretable aquí.

Cierre

Síntesis

  • Las distribuciones modelan la incertidumbre; d, p, q y r son la interfaz común en R.
  • Binomial y Poisson modelan conteos; exponencial y normal, mediciones continuas.
  • Toda prueba sigue la misma lógica: \(H_0\), \(\alpha\), estadístico, valor p y conclusión.
  • ANOVA compara k medias; Tukey identifica qué grupos difieren.
  • Sin diagnóstico de supuestos, las conclusiones de la regresión no son confiables.

Ejercicios propuestos

  1. Proceso con 3 % de defectuosos, lotes de 50: calcule P(X = 0) y P(X ≥ 3).
  2. ¿La longitud media del pico de Gentoo difiere de 47 mm? Verifique normalidad.
  3. Compare la masa de machos y hembras de Chinstrap (Welch y Mann-Whitney).
  4. ANOVA de Sepal.Width por especie en iris, con supuestos y Tukey.
  5. Ajuste lm(mpg ~ wt + hp + am); interprete y compárelo con m2 mediante anova().

Referencias

  • Couch, S. P., et al. (2021). infer: An R package for tidyverse-friendly statistical inference. JOSS, 6(65), 3661.
  • Çetinkaya-Rundel, M., & Hardin, J. (2021). Introduction to modern statistics. OpenIntro.
  • Delacre, M., Lakens, D., & Leys, C. (2017). Why psychologists should by default use Welch’s t-test. International Review of Social Psychology, 30(1), 92–101.
  • Diez, D., Çetinkaya-Rundel, M., & Barr, C. D. (2019). OpenIntro statistics (4th ed.). OpenIntro.
  • Fox, J., & Weisberg, S. (2019). An R companion to applied regression (3rd ed.). Sage.
  • Ismay, C., & Kim, A. Y. (2020). Statistical inference via data science: A ModernDive into R and the tidyverse. CRC Press.
  • Montgomery, D. C., & Runger, G. C. (2014). Applied statistics and probability for engineers (6th ed.). Wiley.
  • Robinson, D., Hayes, A., & Couch, S. (2024). broom [R package].
  • Wickham, H., Çetinkaya-Rundel, M., & Grolemund, G. (2023). R for data science (2nd ed.). O’Reilly.