2  Introducción a los Modelos Multinivel

2.1 Dos formas equivalentes de entenderlos

  1. Generalización de la regresión lineal clásica:

    • Modelo de regresión con un predictor:

      \[ y_{i} = \alpha + \beta x_{i} + \epsilon_{i} \]

    • Modelo de intercepto variable:

      \[ y_{i} = \alpha_{j[i]} + \beta x_{i} + \epsilon_{i} \]

    • Modelo de intercepto y pendiente variables:

      \[ y_{i} = \alpha_{j[i]} + \beta_{j[i]} x_{i} + \epsilon_{i} \]

  2. Regresión con variable categórica de pertenencia a grupo:

    • El índice de grupo es un factor con \(J\) niveles, correspondientes a \(J\) predictores (o \(2J\) si se incluyen interacciones con un predictor \(x\), \(3J\) si hay interacciones con dos predictores \(X_{(1)}, X_{(2)}\), etc.).
    • Se añaden \(J-1\) predictores lineales (equivalente a reemplazar la constante por \(J\) interceptos).

Paso clave en el modelado multinivel

Los \(J\) coeficientes no se estiman de manera independiente, sino que se modelan mediante una distribución de nivel superior, por ejemplo:

\[ \alpha_{j} \sim N(\mu_\alpha, \sigma_\alpha^2) \]

El modelo de nivel de grupo se estima simultáneamente con la regresión de nivel de datos de \(y\).


2.2 Notación

2.2.1 Regresión clásica

  • Unidades: \(i=1, \ldots, n\)

  • Variables de respuesta: \(y = (y_1, \ldots, y_n)\)

  • Predictores: matriz \(X\) de dimensión \(n \times k\)

    • Predicciones: \(\hat{y} = X \beta\)
    • Incluye término constante (columna de 1’s).
  • Coeficientes: \(\beta_0, \ldots, \beta_{k-1}\)

  • Predictores por unidad: \(X_i\) (fila \(i\) de \(X\)),

    \[ \hat{y}_i = X_i \beta \]

  • Columnas de \(X\): \(X_{(\kappa)}\) representa la columna \((\kappa+1)\) de \(X\).

2.2.2 Modelos multinivel

  • Grupos: \(j=1, \ldots, J\)
  • Segundo nivel de agrupación: \(k=1, \ldots, K\) (ejemplo: estudiantes dentro de escuelas dentro de distritos).
  • Variables índice: \(j[i]\) indica el grupo del individuo \(i\).

2.2.2.1 Notación de coeficientes

  • Se usan \(\alpha, \beta\) para parámetros de nivel individual, y \(\gamma\) para parámetros de nivel grupal.
  • En código R y JAGS: a, b, g.

2.2.2.2 Modelos básicos

  • Intercepto variable con un predictor:

    \[ y_i = \alpha_{j[i]} + \beta x_i + \epsilon_i, \quad y_i \sim N(\alpha_{j[i]} + \beta x_i, \sigma_y^2) \]

  • Intercepto y pendiente variables:

    \[ y_i = \alpha_{j[i]} + \beta_{j[i]} x_i + \epsilon_i, \quad y_i \sim N(\alpha_{j[i]} + \beta_{j[i]} x_i, \sigma_y^2) \]

  • Con múltiples predictores:

    \[ y_i = X_i B + \epsilon_i, \quad y_i \sim N(X_i B, \sigma_y^2) \]

    donde \(B\) es una matriz de coeficientes que puede modelarse con interceptos y pendientes variables.

2.2.2.3 Notación de varianzas

  • Errores a nivel de datos: \(\sigma_y\)
  • Errores a nivel de grupo: \(\sigma_\alpha, \sigma_\beta, \ldots\)

2.2.2.4 Predictores de nivel de grupo

Representados en matriz \(U\) de \(J\) filas:

\[ \alpha_j \sim N(U_j \gamma, \sigma_\alpha^2) \]

Si existe un único predictor de nivel grupal, se denota \(u\).

2.3 Pooling parcial sin predictores

En esta sección se presentan los conceptos de pooling completo, no pooling y pooling parcial en el contexto del modelado multinivel. Se ilustra con el ejemplo de los niveles de radón en viviendas de los 85 condados de Minnesota. El objetivo es comprender cómo el modelado multinivel actúa como un compromiso entre ignorar la variación entre grupos y sobreajustar modelos independientes por grupo.

2.3.1 Estimaciones con pooling completo y sin pooling

Ejemplo: estimar la distribución de niveles de radón en casas de 85 condados en Minnesota.

  • Pooling completo: se usa un único promedio para todas las casas en los 85 condados; ignora la variación real entre condados.
  • No pooling: se estima el promedio del log del radón para cada condado; sobreajusta los datos cuando hay pocas observaciones por condado (estimaciones muy variables). Un condado con solo dos mediciones puede aparecer como extremo sin suficiente evidencia.

Conclusión: el no pooling exagera la variación entre condados, mientras que el pooling completo la ignora.

Objetivo del bloque de código: Cargar y depurar los datos de radón, crear variables de trabajo y codificar el identificador de condado.

# Carga y preparación de datos de radón (Minnesota)
radon <- read_delim("../ARM_Data/radon/srrs2.dat", trim_ws = TRUE)
Rows: 12777 Columns: 25
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (11): state, state2, zip, basement, rep, wave, starttm, stoptm, startdt,...
dbl (13): idnum, stfips, region, typebldg, floor, room, stratum, activity, p...
lgl  (1): windoor

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
radon_data <- radon %>%
  filter(state == "MN") %>%                             # mantener observaciones de Minnesota
  mutate(
    radon = activity,                                   # nivel de radón (escala original)
    log_radon = log(if_else(activity == 0, 0.1, activity)), # escala log (evitar log(0))
    floor = floor,                                      # 0 = sótano, 1 = primer piso (según datos)
    county_name = as.vector(county)                     # nombre de condado
  ) %>%
  group_by(county_name) %>%
  mutate(county = cur_group_id()) %>%                   # id numérico de condado
  ungroup()

Objetivo del bloque de código: Visualizar la distribución de log_radon por condado y marcar la media global (pooling completo).

# Media global (pooling completo) en escala log
mean_radon <- mean(radon_data$log_radon, na.rm = TRUE)

# Boxplot por condado con línea horizontal en la media global
ggplot(radon_data, aes(x = county_name, y = log_radon)) +
  geom_boxplot() +
  geom_abline(intercept = mean_radon, slope = 0, color = "red") +
  labs(title = "Niveles de radón (log) por condado",
       x = "Condado",
       y = "Log(radón)") +
  theme_minimal() +
  theme(axis.text.x = element_blank())  # ocultar etiquetas para legibilidad

Objetivo del bloque de código: Ordenar condados por tamaño muestral y repetir la visualización para enfatizar la inestabilidad con muestras pequeñas (no pooling).

# Tamaño muestral por condado
tabla_ns <- radon_data %>%
  count(county_name, name = "n")

# Ordenar factor por tamaño de muestra
radon_data <- radon_data %>%
  left_join(tabla_ns, by = "county_name") %>%
  mutate(county_name = factor(county_name, levels = tabla_ns$county_name[order(tabla_ns$n)]))

# Boxplot ordenado por n
ggplot(radon_data, aes(x = county_name, y = log_radon)) +
  geom_boxplot() +
  geom_abline(intercept = mean_radon, slope = 0, color = "red") +
  labs(title = "Niveles de radón (log) por condado (ordenado por tamaño muestral)",
       x = "Condado (ordenado por n)",
       y = "Log(radón)") +
  theme_minimal() +
  theme(axis.text.x = element_blank())

2.3.2 Estimaciones con pooling parcial (modelo multinivel)

El modelo multinivel genera estimaciones intermedias. El objetivo es estimar el promedio de radón en logaritmos \(\alpha_j\) para el condado \(j\), a partir de una muestra de tamaño \(n_j\).

El estimador multinivel es un promedio ponderado entre el promedio del condado (\(\bar{y}_j\)) y el promedio general del estado (\(\bar{y}_{\text{all}}\)):

\[ \hat{\alpha}_{j}^{\text{multilevel}} \approx \frac{\frac{n_j}{\sigma_y^2}\,\bar{y}_j + \frac{1}{\sigma_\alpha^2}\,\bar{y}_{\text{all}}} {\frac{n_j}{\sigma_y^2} + \frac{1}{\sigma_\alpha^2}} \]

donde \(n_j\) es el número de casas medidas en el condado \(j\), \(\sigma_y^2\) la varianza dentro de los condados y \(\sigma_\alpha^2\) la varianza entre los promedios de los condados.

Interpretación de los pesos

  • Muestras pequeñas (\(n_j\) pequeño): la estimación se acerca a \(\bar{y}_{\text{all}}\) (si \(n_j=0\), coincide).
  • Muestras grandes (\(n_j \to \infty\)): la estimación coincide con \(\bar{y}_j\).
  • Casos intermedios: la estimación se sitúa entre ambos extremos.

Objetivo del bloque de código: Ajustar un modelo multinivel de interceptos aleatorios por condado y producir valores predichos (pooling parcial).

# Modelo multinivel (intercepto aleatorio por condado)
lmer_radon <- lmer(log_radon ~ 1 + (1 | county_name), data = radon_data)

# Predicción del nivel de radón (log) con pooling parcial
radon_data <- radon_data %>%
  mutate(log_radon_pred = predict(lmer_radon))

# Visualización de las predicciones por condado
ggplot(radon_data, aes(x = county_name, y = log_radon_pred)) +
  geom_boxplot() +
  geom_abline(intercept = mean_radon, slope = 0, color = "red") +
  labs(title = "Predicción (pooling parcial) de log(radón) por condado",
       x = "Condado",
       y = "Log(radón) predicho") +
  theme_minimal() +
  theme(axis.text.x = element_blank())

2.4 Pooling parcial con predictores

En esta sección se estudia el pooling parcial con predictores en modelos multinivel. El principio es el mismo que en los casos sin predictores: encontrar un compromiso entre pooling completo y no pooling. El ejemplo de aplicación corresponde a las mediciones de radón en viviendas de 85 condados de Minnesota, incluyendo como predictor el piso de medición (sótano o primer piso).

2.4.1 Pooling completo y no pooling con predictores

  • Pooling completo: una sola regresión para todos los condados:

\[ y_i = \alpha + \beta x_i + \epsilon_i \]

  • No pooling: regresiones con interceptos específicos por condado pero pendiente común:

\[ y_i = \alpha_{j[i]} + \beta x_i + \epsilon_i \]

donde \(j[i]\) indica el condado de la vivienda \(i\). El pooling completo ignora la variación entre condados; el no pooling tiende a producir estimaciones más extremas en condados con pocas observaciones.

Ejemplo en R del pooling completo:

# Ajuste con pooling completo: mismo intercepto y pendiente
modelo_pooling <- lm(log_radon ~ floor, data = radon_data)
summary(modelo_pooling)

Call:
lm(formula = log_radon ~ floor, data = radon_data)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.6293 -0.5383  0.0342  0.5603  2.5486 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  1.32674    0.02972  44.640   <2e-16 ***
floor       -0.61339    0.07284  -8.421   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.8226 on 917 degrees of freedom
Multiple R-squared:  0.07178,   Adjusted R-squared:  0.07077 
F-statistic: 70.91 on 1 and 917 DF,  p-value: < 2.2e-16

Ejemplo en R del no pooling:

# Ajuste sin pooling: interceptos específicos por condado
modelo_no_pooling <- lm(log_radon ~ floor + factor(county_name) - 1, data = radon_data)
summary(modelo_no_pooling)

Call:
lm(formula = log_radon ~ floor + factor(county_name) - 1, data = radon_data)

Residuals:
     Min       1Q   Median       3Q      Max 
-3.14595 -0.45405  0.00065  0.45376  2.65987 

Coefficients:
                                     Estimate Std. Error t value Pr(>|t|)    
floor                                -0.72054    0.07352  -9.800  < 2e-16 ***
factor(county_name)MAHNOMEN           1.36098    0.75642   1.799 0.072343 .  
factor(county_name)MURRAY             2.49321    0.75642   3.296 0.001022 ** 
factor(county_name)WILKIN             2.23001    0.75642   2.948 0.003286 ** 
factor(county_name)COOK               0.66486    0.53487   1.243 0.214204    
factor(county_name)FILLMORE           1.39999    0.53613   2.611 0.009183 ** 
factor(county_name)LAC QUI PARLE      2.95897    0.53613   5.519 4.55e-08 ***
factor(county_name)MILLE LACS         0.88393    0.53613   1.649 0.099583 .  
factor(county_name)POPE               1.27939    0.53487   2.392 0.016979 *  
factor(county_name)ROCK               1.29912    0.53487   2.429 0.015357 *  
factor(county_name)STEVENS            1.79176    0.53487   3.350 0.000845 ***
factor(county_name)YELLOW MEDICINE    1.18652    0.53487   2.218 0.026801 *  
factor(county_name)BECKER             1.52870    0.43946   3.479 0.000530 ***
factor(county_name)BIG STONE          1.51301    0.43672   3.464 0.000558 ***
factor(county_name)DODGE              1.80032    0.43672   4.122 4.13e-05 ***
factor(county_name)ISANTI             1.05600    0.43672   2.418 0.015818 *  
factor(county_name)KITTSON            1.59044    0.43946   3.619 0.000314 ***
factor(county_name)NOBLES             1.92769    0.43672   4.414 1.15e-05 ***
factor(county_name)NORMAN             1.25080    0.43741   2.860 0.004348 ** 
factor(county_name)PENNINGTON         1.10110    0.43946   2.506 0.012415 *  
factor(county_name)RENVILLE           1.67070    0.43741   3.820 0.000144 ***
factor(county_name)TODD               1.72372    0.43741   3.941 8.80e-05 ***
factor(county_name)WATONWAN           2.70953    0.43946   6.166 1.09e-09 ***
factor(county_name)AITKIN             0.84054    0.37866   2.220 0.026701 *  
factor(county_name)BENTON             1.43257    0.37866   3.783 0.000166 ***
factor(county_name)BROWN              1.98958    0.37999   5.236 2.08e-07 ***
factor(county_name)CHIPPEWA           1.73025    0.37821   4.575 5.49e-06 ***
factor(county_name)CLEARWATER         1.33797    0.37999   3.521 0.000453 ***
factor(county_name)COTTONWOOD         1.27480    0.38221   3.335 0.000890 ***
factor(county_name)KANABEC            1.23629    0.37821   3.269 0.001124 ** 
factor(county_name)KANDIYOHI          2.06187    0.37821   5.452 6.58e-08 ***
factor(county_name)LAKE OF THE WOODS  1.86772    0.37999   4.915 1.07e-06 ***
factor(county_name)LINCOLN            2.31580    0.37866   6.116 1.48e-09 ***
factor(county_name)NICOLLET           2.16504    0.37821   5.724 1.45e-08 ***
factor(county_name)PIPESTONE          1.86092    0.37866   4.915 1.07e-06 ***
factor(county_name)POLK               1.72178    0.37999   4.531 6.73e-06 ***
factor(county_name)SIBLEY             1.24245    0.37821   3.285 0.001062 ** 
factor(county_name)SWIFT              0.98704    0.37821   2.610 0.009223 ** 
factor(county_name)TRAVERSE           2.00844    0.37866   5.304 1.45e-07 ***
factor(county_name)WASECA             0.61488    0.37866   1.624 0.104785    
factor(county_name)CASS               1.40113    0.33828   4.142 3.80e-05 ***
factor(county_name)HUBBARD            1.24159    0.34115   3.639 0.000290 ***
factor(county_name)JACKSON            2.02057    0.33828   5.973 3.45e-09 ***
factor(county_name)LE SUEUR           1.74807    0.33860   5.163 3.05e-07 ***
factor(county_name)MEEKER             1.21461    0.33828   3.591 0.000349 ***
factor(county_name)REDWOOD            1.98301    0.33860   5.856 6.80e-09 ***
factor(county_name)WADENA             1.28569    0.33956   3.786 0.000164 ***
factor(county_name)CARVER             1.56391    0.31099   5.029 6.04e-07 ***
factor(county_name)CHISAGO            1.03872    0.30881   3.364 0.000804 ***
factor(county_name)FARIBAULT          0.63679    0.30905   2.060 0.039663 *  
factor(county_name)HOUSTON            1.77336    0.30978   5.725 1.45e-08 ***
factor(county_name)PINE               0.76218    0.30905   2.466 0.013855 *  
factor(county_name)BELTRAMI           1.55272    0.28897   5.373 1.00e-07 ***
factor(county_name)KOOCHICHING        0.81920    0.28897   2.835 0.004695 ** 
factor(county_name)MARTIN             1.04099    0.28609   3.639 0.000291 ***
factor(county_name)WABASHA            1.82168    0.28609   6.367 3.17e-10 ***
factor(county_name)LYON               1.96715    0.26759   7.351 4.69e-13 ***
factor(county_name)OTTER TAIL         1.61799    0.26885   6.018 2.64e-09 ***
factor(county_name)SHERBURNE          1.09002    0.26743   4.076 5.02e-05 ***
factor(county_name)DOUGLAS            1.73399    0.25227   6.873 1.23e-11 ***
factor(county_name)FREEBORN           2.10162    0.25267   8.318 3.64e-16 ***
factor(county_name)LAKE               0.40209    0.25227   1.594 0.111345    
factor(county_name)MARSHALL           1.60224    0.25543   6.273 5.69e-10 ***
factor(county_name)MORRISON           1.14812    0.25227   4.551 6.13e-06 ***
factor(county_name)CARLTON            1.00304    0.23931   4.191 3.07e-05 ***
factor(county_name)STEELE             1.57990    0.23920   6.605 7.08e-11 ***
factor(county_name)ITASCA             0.92576    0.22807   4.059 5.39e-05 ***
factor(county_name)RICE               1.84784    0.22817   8.099 1.97e-15 ***
factor(county_name)CROW WING          1.12155    0.21913   5.118 3.83e-07 ***
factor(county_name)MCLEOD             1.29541    0.21101   6.139 1.28e-09 ***
factor(county_name)MOWER              1.70211    0.21010   8.102 1.93e-15 ***
factor(county_name)SCOTT              1.80312    0.21101   8.545  < 2e-16 ***
factor(county_name)WINONA             1.62292    0.21048   7.711 3.57e-14 ***
factor(county_name)WRIGHT             1.64535    0.20987   7.840 1.38e-14 ***
factor(county_name)BLUE EARTH         2.01216    0.20243   9.940  < 2e-16 ***
factor(county_name)CLAY               1.98838    0.20325   9.783  < 2e-16 ***
factor(county_name)GOODHUE            1.95072    0.20243   9.636  < 2e-16 ***
factor(county_name)ROSEAU             1.66574    0.20648   8.067 2.50e-15 ***
factor(county_name)OLMSTED            1.30676    0.15802   8.270 5.28e-16 ***
factor(county_name)STEARNS            1.49184    0.15174   9.832  < 2e-16 ***
factor(county_name)RAMSEY             1.15873    0.13389   8.654  < 2e-16 ***
factor(county_name)WASHINGTON         1.32952    0.11181  11.890  < 2e-16 ***
factor(county_name)ANOKA              0.87482    0.10498   8.333 3.23e-16 ***
factor(county_name)DAKOTA             1.33831    0.09541  14.026  < 2e-16 ***
factor(county_name)HENNEPIN           1.36058    0.07422  18.332  < 2e-16 ***
factor(county_name)ST LOUIS           0.86763    0.07096  12.227  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.7564 on 833 degrees of freedom
Multiple R-squared:  0.7671,    Adjusted R-squared:  0.7431 
F-statistic: 31.91 on 86 and 833 DF,  p-value: < 2.2e-16

2.4.1.1 Problemas con pooling completo y no pooling

  • Pooling completo: elimina la variación real entre condados, ocultando el objetivo de identificar condados con niveles altos de radón.
  • No pooling: sobreajusta los datos. Condados con pocas observaciones presentan estimaciones poco confiables, como en el caso de Lac Qui Parle, que aparece con el mayor nivel de radón a pesar de tener solo dos mediciones.

2.4.2 Análisis multinivel

El modelo multinivel combina ambos enfoques, introduciendo un “suavizamiento” de los interceptos:

\[ y_i \sim N(\alpha_{j[i]} + \beta x_i, \sigma_y^2), \quad i=1,\ldots,n \]

Los interceptos \(\alpha_j\) se modelan con una distribución de segundo nivel:

\[ \alpha_j \sim N(\mu_\alpha, \sigma_\alpha^2), \quad j=1,\ldots,J \]

Este planteamiento establece una restricción suave: los interceptos se acercan a \(\mu_\alpha\), pero sin forzarlos a ser idénticos.

  • Cuando \(\sigma_\alpha \to \infty\), no hay pooling.
  • Cuando \(\sigma_\alpha \to 0\), se obtiene pooling completo.

2.4.3 Pooling parcial (shrinkage) de los coeficientes \(\alpha_j\)

La estimación multinivel de \(\alpha_j\) puede expresarse como un promedio ponderado entre la estimación sin pooling para su condado y la media general \(\mu_\alpha\):

\[ \text{estimate of } \alpha_j \approx \frac{\tfrac{n_j}{\sigma_y^2}}{\tfrac{n_j}{\sigma_y^2} + \tfrac{1}{\sigma_\alpha^2}} \, (\bar{y}_j - \beta \bar{x}_j) + \frac{\tfrac{1}{\sigma_\alpha^2}}{\tfrac{n_j}{\sigma_y^2} + \tfrac{1}{\sigma_\alpha^2}} \, \mu_\alpha \tag{12.4} \]

En la práctica, este cálculo se implementa automáticamente con funciones como lmer() o mediante métodos bayesianos.

# Ejemplo de ajuste multinivel en R con lme4
modelo_multinivel <- lmer(log_radon ~ floor + (1 | county_name), data = radon_data)
summary(modelo_multinivel)
Linear mixed model fit by REML ['lmerMod']
Formula: log_radon ~ floor + (1 | county_name)
   Data: radon_data

REML criterion at convergence: 2171.3

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-4.3989 -0.6155  0.0029  0.6405  3.4281 

Random effects:
 Groups      Name        Variance Std.Dev.
 county_name (Intercept) 0.1077   0.3282  
 Residual                0.5709   0.7556  
Number of obs: 919, groups:  county_name, 85

Fixed effects:
            Estimate Std. Error t value
(Intercept)  1.46160    0.05158  28.339
floor       -0.69299    0.07043  -9.839

Correlation of Fixed Effects:
      (Intr)
floor -0.288

2.4.3.1 Línea de regresión promedio y varianzas

Los hiperparámetros estimados en el modelo de radón son:

  • \(\hat{\mu}_\alpha = 1.46\)
  • \(\hat{\beta} = -0.69\)
  • \(\hat{\sigma}_y = 0.76\)
  • \(\hat{\sigma}_\alpha = 0.33\)

La línea de regresión promedio es:

\[ y = 1.46 - 0.69x \]

La relación entre varianzas puede expresarse como:

  • Cociente de varianzas: \(\sigma_\alpha^2 / \sigma_y^2 = 0.19\approx 1/5\). El cual se puede interpretar como que la variabilidad entre condados es aproximadamente una quinta parte de la variabilidad dentro de los condados. Además se puede interpretar a que la desviación estándar entre condados equivale a la desviación estándar del promedio de 5 mediciones dentro de un condado.
  • Correlación intraclase: \(\sigma_\alpha^2 / (\sigma_\alpha^2 + \sigma_y^2)\). Este indicador va de 0 (agrupamiento no informativo) a 1 (todos los miembros del grupo son identicos). En este caso, vale 0.16, indicando que el 16% de la variabilidad total se debe a diferencias entre condados.

2.4.4 Regresión clásica como caso especial

  • Si \(\sigma_\alpha \to 0\), el modelo se reduce a pooling completo.
  • Si \(\sigma_\alpha \to \infty\), se obtiene no pooling.

Los modelos multinivel permiten estimar \(\sigma_\alpha\) directamente a partir de los datos, evitando elegir arbitrariamente uno de los extremos.

2.4.5 Ejemplos gráficos comparativos

2.4.5.1 Pooling completo vs no pooling con una covariable

muestra_counties <- c('LAC QUI PARLE', 'AITKIN','KOOCHICHING',
                      'DOUGLAS','CLAY','STEARNS','RAMSEY','ST LOUIS')

radon_data_r <- radon_data %>% 
  mutate(county_s = as.character(county_name)) %>%
  filter(county_s %in% muestra_counties)

# Pooling completo
regresion_pooling <- lm(log_radon ~ floor, data = radon_data_r)

# No pooling
regresion_no_pooling <- lm(log_radon ~ -1 + floor + county_name, data = radon_data_r)

coef_df <- coef(regresion_no_pooling)

coef_data <- data.frame(
  county_s = sub("county", "", names(coef_df)[grep("county", names(coef_df))]),
  slope = coef_df[grep("floor", names(coef_df))],
  intercept = coef_df[grep("county", names(coef_df))]
)
Warning in data.frame(county_s = sub("county", "",
names(coef_df)[grep("county", : row names were found from a short variable and
have been discarded
radon_data_r <- radon_data_r %>%
  left_join(coef_data, by = "county_s")

ggplot(data = radon_data_r) +
  geom_point(aes(x = floor, y = log_radon)) +
  geom_abline(aes(intercept = intercept, slope = slope), color = "blue") +   # Líneas específicas por condado
  geom_abline(intercept = coef(regresion_pooling)[1], slope = coef(regresion_pooling)[2], color = "red") + # Línea general
  facet_wrap(~county_s) +
  labs(title = "Radon Levels by Floor with Specific and General Regression Lines",
       x = "Floor", y = "Log Radon Level") +
  theme_minimal()
Warning: Removed 209 rows containing missing values or values outside the scale range
(`geom_abline()`).

2.4.5.2 Pooling parcial con una covariable (Multinivel)

lmer_radon_floor <- lmer(log_radon ~ floor + (1|county_name), 
                         data = radon_data_r)

fixed_effect <- fixef(lmer_radon_floor)
random_effects <- ranef(lmer_radon_floor)$county_name

coef_data_lmer <- data.frame(
  county_s = rownames(random_effects),
  intercept_lmer = fixed_effect[1] + random_effects[, 1], 
  slope_lmer = fixed_effect[2]  
)
Warning in data.frame(county_s = rownames(random_effects), intercept_lmer =
fixed_effect[1] + : row names were found from a short variable and have been
discarded
radon_data_r <- radon_data_r %>%
  left_join(coef_data_lmer, by = "county_s")

ggplot(data = radon_data_r) +
  geom_point(aes(x = floor, y = log_radon)) +
  geom_abline(aes(intercept = intercept_lmer, slope = slope_lmer), color = "blue") +  # Regresiones por condado
  geom_abline(intercept = fixed_effect[1], slope = fixed_effect[2], color = "red") +  # Línea general (efectos fijos)
  facet_wrap(~county_s) +
  labs(title = "Radon Levels by Floor with Specific and General Regression Lines (Multilevel)",
       x = "Floor", y = "Log Radon Level") +
  theme_minimal()

2.5 Ajuste rápido de modelos multinivel en R

En esta sección se presenta cómo ajustar modelos multinivel de manera rápida en R utilizando la función lmer(). Estos modelos permiten estimar interceptos y pendientes que pueden variar entre grupos. Se ilustra el procedimiento con los datos de radón, donde las viviendas están anidadas en condados.

2.5.1 Modelo con intercepto variable sin predictores

El modelo más sencillo incluye únicamente un intercepto que varía entre condados:

\[ y_i = \alpha_{j[i]} + \epsilon_i, \quad \alpha_j \sim N(\mu_\alpha, \sigma_\alpha^2) \]

MO <- lmer(log_radon ~ 1 + (1 | county), data = radon_data)
summary(MO)
Linear mixed model fit by REML ['lmerMod']
Formula: log_radon ~ 1 + (1 | county)
   Data: radon_data

REML criterion at convergence: 2259.4

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-4.4661 -0.5734  0.0441  0.6432  3.3516 

Random effects:
 Groups   Name        Variance Std.Dev.
 county   (Intercept) 0.09581  0.3095  
 Residual             0.63662  0.7979  
Number of obs: 919, groups:  county, 85

Fixed effects:
            Estimate Std. Error t value
(Intercept)  1.31258    0.04891   26.84

2.5.2 Modelo con intercepto variable y un predictor individual

Ahora se añade el predictor a nivel individual (piso de medición):

\[ y_i = \alpha_{j[i]} + \beta x_i + \epsilon_i, \quad \alpha_j \sim N(\mu_\alpha, \sigma_\alpha^2) \]

M1 <- lmer(log_radon ~ floor + (1 | county), data = radon_data)
summary(M1)
Linear mixed model fit by REML ['lmerMod']
Formula: log_radon ~ floor + (1 | county)
   Data: radon_data

REML criterion at convergence: 2171.3

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-4.3989 -0.6155  0.0029  0.6405  3.4281 

Random effects:
 Groups   Name        Variance Std.Dev.
 county   (Intercept) 0.1077   0.3282  
 Residual             0.5709   0.7556  
Number of obs: 919, groups:  county, 85

Fixed effects:
            Estimate Std. Error t value
(Intercept)  1.46160    0.05158  28.339
floor       -0.69299    0.07043  -9.839

Correlation of Fixed Effects:
      (Intr)
floor -0.288

Este modelo supone una pendiente común para todos los condados, pero permite interceptos distintos.

2.5.3 Coeficientes estimados por condado

Podemos extraer las líneas de regresión por condado:

coef(M1)
$county
   (Intercept)      floor
1    1.1915004 -0.6929937
2    0.9276468 -0.6929937
3    1.4792143 -0.6929937
4    1.5045012 -0.6929937
5    1.4461503 -0.6929937
6    1.4801817 -0.6929937
7    1.8581255 -0.6929937
8    1.6827736 -0.6929937
9    1.1600747 -0.6929937
10   1.5086099 -0.6929937
11   1.4322449 -0.6929937
12   1.5771520 -0.6929937
13   1.2370518 -0.6929937
14   1.8380232 -0.6929937
15   1.4024982 -0.6929937
16   1.2432992 -0.6929937
17   1.3723633 -0.6929937
18   1.2209415 -0.6929937
19   1.3462611 -0.6929937
20   1.5840332 -0.6929937
21   1.6311136 -0.6929937
22   1.0211903 -0.6929937
23   1.4409443 -0.6929937
24   1.8605721 -0.6929937
25   1.8135585 -0.6929937
26   1.3626875 -0.6929937
27   1.6222663 -0.6929937
28   1.3467692 -0.6929937
29   1.3149879 -0.6929937
30   1.0999775 -0.6929937
31   1.7329562 -0.6929937
32   1.3646863 -0.6929937
33   1.7197950 -0.6929937
34   1.5015319 -0.6929937
35   1.0870316 -0.6929937
36   1.8680899 -0.6929937
37   0.7928242 -0.6929937
38   1.6303574 -0.6929937
39   1.5979922 -0.6929937
40   1.8260564 -0.6929937
41   1.7636308 -0.6929937
42   1.4456250 -0.6929937
43   1.5404841 -0.6929937
44   1.2199767 -0.6929937
45   1.3375197 -0.6929937
46   1.3416955 -0.6929937
47   1.2995481 -0.6929937
48   1.2623708 -0.6929937
49   1.6294468 -0.6929937
50   1.6253580 -0.6929937
51   1.7641693 -0.6929937
52   1.6300755 -0.6929937
53   1.3820836 -0.6929937
54   1.3328317 -0.6929937
55   1.5494611 -0.6929937
56   1.3246513 -0.6929937
57   1.0877739 -0.6929937
58   1.6303984 -0.6929937
59   1.5675867 -0.6929937
60   1.4116740 -0.6929937
61   1.1995431 -0.6929937
62   1.7120492 -0.6929937
63   1.5338618 -0.6929937
64   1.7205672 -0.6929937
65   1.4170797 -0.6929937
66   1.5982671 -0.6929937
67   1.6981946 -0.6929937
68   1.2380854 -0.6929937
69   1.3673371 -0.6929937
70   0.8899487 -0.6929937
71   1.4829168 -0.6929937
72   1.5389227 -0.6929937
73   1.5520593 -0.6929937
74   1.2574763 -0.6929937
75   1.5530274 -0.6929937
76   1.6938490 -0.6929937
77   1.6642922 -0.6929937
78   1.3708520 -0.6929937
79   1.0944378 -0.6929937
80   1.3404792 -0.6929937
81   1.9060482 -0.6929937
82   1.5835784 -0.6929937
83   1.5716875 -0.6929937
84   1.5906331 -0.6929937
85   1.3862294 -0.6929937

attr(,"class")
[1] "coef.mer"

Esto muestra que las pendientes son iguales en todos los condados (por construcción), mientras que los interceptos varían.

2.5.4 Efectos fijos y aleatorios

Los efectos fijos corresponden a la regresión promedio:

fixef(M1)
(Intercept)       floor 
  1.4615979  -0.6929937 

Los efectos aleatorios muestran las desviaciones específicas de cada condado:

ranef(M1)
$county
   (Intercept)
1  -0.27009750
2  -0.53395107
3   0.01761646
4   0.04290331
5  -0.01544759
6   0.01858386
7   0.39652761
8   0.22117571
9  -0.30152320
10  0.04701206
11 -0.02935302
12  0.11555412
13 -0.22454606
14  0.37642528
15 -0.05909970
16 -0.21829868
17 -0.08923455
18 -0.24065633
19 -0.11533676
20  0.12243536
21  0.16951571
22 -0.44040759
23 -0.02065353
24  0.39897419
25  0.35196058
26 -0.09891042
27  0.16066845
28 -0.11482866
29 -0.14661001
30 -0.36162037
31  0.27135836
32 -0.09691159
33  0.25819715
34  0.03993398
35 -0.37456628
36  0.40649202
37 -0.66877366
38  0.16875953
39  0.13639435
40  0.36445852
41  0.30203292
42 -0.01597290
43  0.07888623
44 -0.24162113
45 -0.12407819
46 -0.11990235
47 -0.16204982
48 -0.19922711
49  0.16784892
50  0.16376017
51  0.30257145
52  0.16847763
53 -0.07951423
54 -0.12876622
55  0.08786324
56 -0.13694655
57 -0.37382399
58  0.16880050
59  0.10598884
60 -0.04992385
61 -0.26205479
62  0.25045135
63  0.07226395
64  0.25896934
65 -0.04451816
66  0.13666918
67  0.23659674
68 -0.22351243
69 -0.09426076
70 -0.57164915
71  0.02131895
72  0.07732481
73  0.09046140
74 -0.20412162
75  0.09142952
76  0.23225113
77  0.20269435
78 -0.09074583
79 -0.36716012
80 -0.12111867
81  0.44445030
82  0.12198051
83  0.11008961
84  0.12903524
85 -0.07536845

with conditional variances for "county" 

2.5.5 Incertidumbre en los coeficientes estimados

Para obtener errores estándar de los efectos fijos y aleatorios se pueden usar funciones auxiliares:

# Errores estándar de los efectos fijos
se.fixef(M1)
(Intercept)       floor 
 0.05157622  0.07043081 
# Errores estándar de los efectos aleatorios
se.ranef(M1)
$county
   (Intercept)
1   0.24777407
2   0.09981833
3   0.26227669
4   0.21544774
5   0.24777407
6   0.26227669
7   0.17199375
8   0.24777407
9   0.19317328
10  0.22477917
11  0.23543856
12  0.24777407
13  0.22477917
14  0.17199375
15  0.24777407
16  0.27966563
17  0.24777407
18  0.18166402
19  0.09142752
20  0.26227669
21  0.19981370
22  0.22477917
23  0.27966563
24  0.19981370
25  0.17199375
26  0.07194472
27  0.22477917
28  0.23543856
29  0.26227669
30  0.18715375
31  0.23543856
32  0.24777407
33  0.24777407
34  0.26227669
35  0.21544774
36  0.27966563
37  0.19981370
38  0.24777407
39  0.23543856
40  0.24777407
41  0.20718963
42  0.30104582
43  0.19981370
44  0.21544774
45  0.17663065
46  0.23543856
47  0.27966563
48  0.19981370
49  0.17663065
50  0.30104582
51  0.24777407
52  0.26227669
53  0.26227669
54  0.14203531
55  0.20718963
56  0.26227669
57  0.22477917
58  0.24777407
59  0.24777407
60  0.27966563
61  0.12371837
62  0.23543856
63  0.26227669
64  0.18715375
65  0.27966563
66  0.17199375
67  0.17663065
68  0.20718963
69  0.24777407
70  0.06860507
71  0.13726758
72  0.19317328
73  0.27966563
74  0.24777407
75  0.26227669
76  0.24777407
77  0.21544774
78  0.23543856
79  0.24777407
80  0.10549434
81  0.26227669
82  0.30104582
83  0.17663065
84  0.17663065
85  0.27966563

Los errores estándar de los interceptos varían según el tamaño de muestra en cada condado.

2.5.6 Intervalos de confianza

Ejemplo de cálculo de intervalo de confianza del 95% para la pendiente \(\beta\):

fixef(M1)["floor"] + c(-1, 1)*qnorm(0.975)*se.fixef(M1)["floor"]
[1] -0.8310356 -0.5549519

También se puede calcular para un intercepto específico:

coef(M1)$county[26,1] + c(-1,1)*qnorm(0.975)*se.ranef(M1)$county[26]
[1] 1.221678 1.503697

2.5.7 Visualización del modelo ajustado

Podemos comparar pooling completo, no pooling y pooling parcial (multinivel):

a.hat.M1 <- coef(M1)$county[,1] # interceptos
b.hat.M1 <- coef(M1)$county[,2] # pendientes (iguales aquí)

x.jitter <- radon_data$floor + runif(nrow(radon_data), -0.05, 0.05)

# Ejemplo con algunos condados seleccionados
#display8 <- sample(unique(radon_data$county), 8)
display8 <- unique(radon_data_r$county)

par(mfrow=c(2,4))
for (j in display8) {
  idx <- radon_data$county == j
  plot(x.jitter[idx], radon_data$log_radon[idx],
       xlim=c(-.05,1.05), ylim=range(radon_data$log_radon),
       xlab="Floor", ylab="Log radon level", main=j)
  
  # Línea de pooling completo
  abline(coef(lm(log_radon ~ floor, data = radon_data)), lty=2, col="gray40")
  
  # Línea de no pooling
  abline(coef(lm(log_radon ~ floor, data = radon_data[idx,])), col="gray60")
  
  # Línea multinivel
  abline(a.hat.M1[j], b.hat.M1[j], col="black")
}

2.5.8 Modelos más complejos

La función lmer() permite ajustar modelos con interceptos y pendientes que varían entre grupos, predictores de nivel superior y estructuras más complejas. En casos con pocos grupos o modelos complicados, puede ser conveniente emplear métodos bayesianos como JAGS, que permiten un tratamiento más detallado de la incertidumbre.

2.6 Cinco formas de escribir el mismo modelo

En esta sección se presentan cinco formas equivalentes de expresar un modelo multinivel. El contexto es el análisis de radón en viviendas de condados de Minnesota, donde se dispone de predictores a nivel individual (por ejemplo, el piso donde se tomó la medición) y a nivel de condado (el logaritmo del contenido de uranio en el suelo). Se muestra cómo un mismo modelo puede representarse de manera diferente, ya sea mediante regresiones locales, modelos mixtos, errores correlacionados o matrices de diseño ampliadas.

2.6.1 Coeficientes de regresión que varían entre grupos

El modelo de regresión clásico es:

\[ y_i = \beta_0 + \beta_1 X_{i1} + \beta_2 X_{i2} + \cdots + \epsilon_i \]

Generalizando a un modelo multinivel, los coeficientes pueden variar por grupo:

\[ y_i = \beta_{0j[i]} + \beta_{1j[i]} X_{i1} + \beta_{2j[i]} X_{i2} + \cdots + \epsilon_i \]

En el caso de radón, con piso y uranio a nivel de condado:

\[ y_i = \alpha_{j[i]} + \beta_1 X_{i1} + \beta_2 X_{i2} + \epsilon_i \]

En notación matricial:

\[ y_i = \alpha_{j[i]} + X_i \beta + \epsilon_i \]

donde \(X\) incluye el indicador de primer piso y el uranio (con repeticiones), pero no el intercepto. El segundo nivel es:

\[ \alpha_j \sim N(\mu_\alpha, \sigma_\alpha^2) \]

o, equivalentemente,

\[ \alpha_j = \mu_\alpha + \eta_j, \quad \eta_j \sim N(0, \sigma_\alpha^2) \]

Nota: esta es la notación que usa lmer.

2.6.2 Combinando regresiones locales

Otra representación considera regresiones separadas por condado:

\[ y_i \sim N(\alpha_j + \beta x_i, \sigma_y^2), \quad i=1,\ldots,n_j \]

El predictor de uranio entra en el segundo nivel:

\[ \alpha_j \sim N(\gamma_0 + \gamma_1 u_j, \sigma_\alpha^2) \]

o bien,

\[ \alpha_j = \gamma_0 + \gamma_1 u_j + \eta_j, \quad \eta_j \sim N(0,\sigma_\alpha^2) \]

2.6.3 Modelo como regresión única con gran matriz \(X\)

Se puede expresar como:

\[ y_i \sim N(X_i \beta, \sigma_y^2) \]

donde \(X\) incluye:

  • Constante (\(X_{(0)}\)),
  • Piso de la vivienda (\(X_{(1)}\)),
  • Uranio a nivel de condado (\(X_{(2)}\)),
  • Indicadores de condado (\(X_{(3)},\ldots,X_{(J+2)}\)).

Los coeficientes de condado siguen:

\[ \beta_j \sim N(0,\sigma_\alpha^2), \quad j=3,\ldots,J+2 \]

Alternativamente, moviendo la constante:

\[ y_i \sim N(X_i \beta, \sigma_y^2), \quad \beta_j \sim N(\mu_\alpha,\sigma_\alpha^2) \]

2.6.4 Regresión con múltiples términos de error

Otra formulación es el modelo mixto:

\[ y_i \sim N(X_i \beta + \eta_{j[i]}, \sigma_y^2), \quad \eta_j \sim N(0,\sigma_\alpha^2) \]

Aquí \(X\) contiene intercepto, piso y uranio.

2.6.5 Regresión clásica con errores correlacionados

Finalmente, el modelo puede verse como una regresión con errores correlacionados:

\[ y_i = X_i \beta + \epsilon_i^{\text{all}}, \quad \epsilon^{\text{all}} \sim N(0,\Sigma) \]

donde \(\epsilon_i^{\text{all}} = \eta_{j[i]} + \epsilon_i\). La matriz \(\Sigma\) se caracteriza por:

\[ \Sigma_{ii} = \sigma_y^2 + \sigma_\alpha^2, \quad \Sigma_{ik} = \begin{cases} \sigma_\alpha^2 & \text{si } j[i]=j[k] \\ 0 & \text{si } j[i]\neq j[k] \end{cases} \]

En términos de desviaciones estándar y correlaciones:

\[ \operatorname{sd}(\epsilon_i) = \sqrt{\sigma_y^2 + \sigma_\alpha^2}, \quad \operatorname{corr}(\epsilon_i,\epsilon_k) = \begin{cases} \frac{\sigma_\alpha^2}{\sigma_y^2 + \sigma_\alpha^2} & j[i]=j[k] \\ 0 & j[i]\neq j[k] \end{cases} \]

2.7 Predictores a nivel de grupo

Se añade un predictor de nivel de grupo para mejorar la inferencia de los coeficientes de grupo \(\alpha_j\). Continuamos con el ejemplo de radón: modelo con predictor individual (piso, \(x_i\)) y un predictor a nivel de condado (log de uranio del suelo, \(u_j\)). Mostramos cómo integrar ambos niveles en un modelo multinivel, cómo extraer e interpretar los coeficientes, y cómo el predictor de grupo reduce la variación entre condados.

Carga de datos:

cty <- read_delim('../ARM_Data/radon/cty.dat',trim_ws = TRUE)
Rows: 3194 Columns: 7
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (4): stfips, ctfips, st, cty
dbl (3): lon, lat, Uppm

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
radon_data <- radon_data %>% mutate(fips = stfips * 1000 + cntyfips)

# Obtener el FIPS a nivel de EE.UU.
usa.fips <- 1000 * as.numeric(cty$stfips) + as.numeric(cty$ctfips)

# Encontrar las filas correspondientes a los condados únicos en Minnesota
usa.rows <- match(unique(radon_data$fips), usa.fips)

uranium <- cty[usa.rows, "Uppm"]
u <- log(uranium)

county_u_data <- data.frame(
  county_name = unique(radon_data$county_name),
  u = u
)

radon_data <- radon_data %>%
  left_join(county_u_data, by = "county_name") %>% 
  rename(u = Uppm)

2.7.1 Agregar un predictor de nivel de grupo para mejorar la inferencia de \(\alpha_j\)

Formulación jerárquica con predictor individual \(x_i\) (piso) y predictor de condado \(u_j\) (uranio):

\[ \begin{aligned} y_i &\sim \mathrm{N}\!\left(\alpha_{j[i]}+\beta x_i,\;\sigma_y^2\right), \quad i=1,\ldots,n \\ \alpha_j &\sim \mathrm{N}\!\left(\gamma_0+\gamma_1 u_j,\;\sigma_\alpha^2\right), \quad j=1,\ldots,J. \end{aligned} \]

Objetivo del bloque de código

Ajustar el modelo multinivel con intercepto aleatorio por condado e incluir el predictor de condado (uranio) en la parte fija. Se asume que el data.frame radon_data contiene:

  • log_radon: respuesta en log,
  • floor: indicador de piso (0 = sótano, 1 = primer piso),
  • u: medida (log) de uranio por condado,
  • county_name: factor de condado.
# Ajuste del modelo multinivel con predictor de grupo (uranio) y predictor individual (piso)
M2 <- lmer(log_radon ~ floor + u + (1 | county_name), data = radon_data)

# Resumen amigable del ajuste (coeficientes fijos y varianzas de niveles)
display(M2)
lmer(formula = log_radon ~ floor + u + (1 | county_name), data = radon_data)
            coef.est coef.se
(Intercept)  1.47     0.04  
floor       -0.67     0.07  
u            0.72     0.09  

Error terms:
 Groups      Name        Std.Dev.
 county_name (Intercept) 0.16    
 Residual                0.76    
---
number of obs: 919, groups: county_name, 85
AIC = 2144.2, DIC = 2111.4
deviance = 2122.8 

2.7.2 Extracción e interpretación de coeficientes

El modelo promedio sobre condados es: \(y_i = \text{Intercepto} + \beta x_i + \gamma u_{j[i]}\).

  • Efectos fijos (fixef): promedios sobre condados.
  • Efectos aleatorios (ranef): desviaciones de cada condado respecto al promedio.
  • coef(M2): combina fijos + aleatorios para obtener coeficientes por condado.

Objetivo del bloque de código

Extraer efectos fijos y aleatorios, y construir la ecuación por condado con base en la salida del modelo.

# Efectos fijos (promedio sobre condados)
fx <- fixef(M2)

# Efectos aleatorios por condado (desviación de intercepto)
re_county <- ranef(M2)$county_name %>%
  rownames_to_column(var = "county_name") %>%
  as_tibble() %>%
  rename(rand_intercept = `(Intercept)`)

# Coeficientes por condado (intercepto específico + pendientes fijas)
coef_county <- coef(M2)$county_name %>%
  rownames_to_column(var = "county_name") %>%
  as_tibble()

# Vista rápida
head(fx)
(Intercept)       floor           u 
  1.4657628  -0.6682448   0.7202676 
head(re_county)
# A tibble: 6 × 2
  county_name   rand_intercept
  <chr>                  <dbl>
1 MAHNOMEN            -0.00867
2 MURRAY               0.0302 
3 WILKIN               0.0242 
4 COOK                -0.0343 
5 FILLMORE            -0.0306 
6 LAC QUI PARLE        0.0974 
head(coef_county)
# A tibble: 6 × 4
  county_name   `(Intercept)`  floor     u
  <chr>                 <dbl>  <dbl> <dbl>
1 MAHNOMEN               1.46 -0.668 0.720
2 MURRAY                 1.50 -0.668 0.720
3 WILKIN                 1.49 -0.668 0.720
4 COOK                   1.43 -0.668 0.720
5 FILLMORE               1.44 -0.668 0.720
6 LAC QUI PARLE          1.56 -0.668 0.720

2.7.3 Interpretación dentro de condados

El modelo promedio estimado: \(y_i = \hat{\mu}_{\alpha} - \hat{\beta}x_i + \hat{\gamma}u_{j[i]}\). Para un condado particular (p. ej., 85), la línea ajustada puede obtenerse:

  • desde coef(M2) (intercepto específico + pendientes fijas),
  • o como fixef(M2) más el ajuste del intercepto dado por ranef(M2).

Objetivo del bloque de código

Ilustrar cómo calcular la línea ajustada para un condado específico a partir de las salidas fixef, ranef y coef.

# Seleccione un condado de ejemplo (ajustar el nombre según exista en radon_data)
ejemplo_county <- radon_data %>% pull(county_name) %>% as.character() %>% unique() %>% .[1]

# Línea con coeficientes específicos por condado desde coef(M2)
coef_ejemplo <- coef_county %>% filter(county_name == ejemplo_county)

intercepto_ej <- coef_ejemplo$`(Intercept)`
beta_floor_ej  <- coef_ejemplo$floor
gamma_u_ej     <- coef_ejemplo$u

# Alternativa: fixed effects + random intercept
rand_adj <- re_county %>% filter(county_name == ejemplo_county) %>% pull(rand_intercept)
intercepto_via_fx_re <- fx[1] + rand_adj  # (Intercepto promedio + desviación de condado)
beta_via_fx          <- fx["floor"]
gamma_via_fx         <- fx["u"]

tibble(
  county_name = ejemplo_county,
  intercepto_via_coef = intercepto_ej,
  intercepto_via_fx_re = intercepto_via_fx_re,
  beta_floor_via_coef = beta_floor_ej,
  beta_floor_via_fx   = beta_via_fx,
  gamma_u_via_coef    = gamma_u_ej,
  gamma_u_via_fx      = gamma_via_fx
)
# A tibble: 1 × 7
  county_name intercepto_via_coef intercepto_via_fx_re beta_floor_via_coef
  <chr>                     <dbl>                <dbl>               <dbl>
1 AITKIN                     1.45                 1.45              -0.668
# ℹ 3 more variables: beta_floor_via_fx <dbl>, gamma_u_via_coef <dbl>,
#   gamma_u_via_fx <dbl>

2.7.4 Efecto del predictor de grupo en la variación entre condados

La inclusión de \(u_j\) no cambia la variación dentro de condado (\(\sigma_y\)), pero reduce la variación entre condados (\(\sigma_\alpha\)), al explicar parte de la heterogeneidad sistemática de los interceptos con un predictor de nivel grupo.

Objetivo del bloque de código

Extraer las desviaciones estándar estimadas a nivel condado (intercepto aleatorio) y residual para discutir \(\hat{\sigma}_\alpha\) y \(\hat{\sigma}_y\).

# Extraer componentes de varianza del modelo
vc <- VarCorr(M2)
sd_alpha <- attr(vc$county_name, "stddev")[1]   # sd del intercepto a nivel condado
sd_y     <- attr(vc, "sc")                      # sd residual (nivel individual)

tibble(
  `sd_intercepto_condado (hat{sigma}_alpha)` = sd_alpha,
  `sd_residual (hat{sigma}_y)` = sd_y
)
# A tibble: 1 × 2
  `sd_intercepto_condado (hat{sigma}_alpha)` `sd_residual (hat{sigma}_y)`
                                       <dbl>                        <dbl>
1                                      0.156                        0.758

2.7.5 Visualización: intercepto por condado vs. uranio de condado

La estimación de \(\alpha_j\) se encoge hacia la regresión de nivel grupo \(\alpha_j = \gamma_0 + \gamma_1 u_j\). Para ilustrarlo, graficamos el intercepto estimado por condado frente a la media de uranio de su condado y sobreponemos la recta de regresión.

2.7.6 Objetivo del bloque de código

Construir un resumen por condado (media de u) y el intercepto específico estimado; luego, graficar y ajustar una recta para visualizar la relación.

# Media de uranio por condado
u_county <- radon_data %>%
  group_by(county_name) %>%
  summarise(u_mean = mean(u, na.rm = TRUE), .groups = "drop")

# Intercepto específico por condado desde coef(M2)
intercepts_county <- coef_county %>%
  dplyr::select(county_name, `(Intercept)`) %>%
  rename(a_hat = `(Intercept)`)

# Unimos para graficar: intercepto vs uranio
plot_data <- u_county %>%
  inner_join(intercepts_county, by = "county_name")

# Gráfico: puntos + recta OLS de referencia
ggplot(plot_data, aes(x = u_mean, y = a_hat)) +
  geom_point(alpha = 0.8) +
  geom_smooth(method = "lm", formula = y ~ x, se = FALSE) +
  labs(
    x = "Medida de uranio a nivel de condado (u)",
    y = "Intercepto estimado por condado (â_j)",
    title = "Intercepto por condado vs. uranio (pooling hacia la regresión de nivel grupo)"
  ) +
  theme_minimal()

2.7.7 Inclusión de indicadores de condado y predictor de condado

En regresión clásica, los indicadores de condado junto con un predictor de condado suelen ser colineales. En el modelo multinivel, este problema se evita porque los \(\alpha_j\) se modelan con pooling parcial hacia la regresión de nivel grupo, permitiendo estimar simultáneamente los interceptos por condado y la pendiente de \(u_j\).

2.7.8 Pooling parcial de \(\alpha_j\) con predictores de grupo

Con \(\alpha_j \sim \mathrm{N}(U_j\gamma,\sigma_\alpha^2)\), los \(\alpha_j\) se encogen hacia \(\hat{\alpha}_j=U_j\gamma\). De forma aproximada, la estimación de \(\alpha_j\) combina la evidencia del grupo \(j\) y la de la regresión de nivel grupo:

\[ \begin{aligned} \text{estimate of } \alpha_j \approx \frac{\frac{n_j}{\sigma_y^2}}{\frac{n_j}{\sigma_y^2}+\frac{1}{\sigma_\alpha^2}} \cdot (\text{estimate from group } j) +\frac{\frac{1}{\sigma_\alpha^2}}{\frac{n_j}{\sigma_y^2}+\frac{1}{\sigma_\alpha^2}} \cdot (\text{estimate from regression}). \end{aligned} \]

Equivalente para los errores de nivel grupo \(\eta_j\):

\[ \text{estimate of } \eta_j \approx \frac{\frac{n_j}{\sigma_y^2}}{\frac{n_j}{\sigma_y^2}+\frac{1}{\sigma_\alpha^2}} \left(\bar{y}_j-\bar{X}_j\beta-U_j\gamma\right) +\frac{\frac{1}{\sigma_\alpha^2}}{\frac{n_j}{\sigma_y^2}+\frac{1}{\sigma_\alpha^2}}\cdot 0. \]

2.8 Construcción de modelos y significancia estadística

2.8.1 De regresión clásica a regresión multinivel

Ante datos multinivel, se recomienda comenzar con modelos clásicos sencillos y avanzar hacia un modelo multinivel completo. Cuatro puntos de partida naturales:

  • Modelo de pooling completo: una sola regresión clásica que ignora la información de grupos (un único modelo para todos los datos), pudiendo incluir predictores de nivel grupo pero sin coeficientes por indicadores de grupo.
  • Modelo sin pooling: una sola regresión clásica que incluye indicadores de grupo (sin predictores de nivel grupo) y sin modelar los coeficientes de grupo.
  • Modelos separados por grupo: una regresión clásica en cada grupo. Puede ser inviable cuando hay grupos con tamaños muestrales pequeños (p. ej., si un condado solo tiene casas con sótano no se puede estimar la pendiente \(\beta\) para ese condado).
  • Análisis en dos pasos: partir del sin pooling o de modelos separados, y luego ajustar una regresión clásica a nivel grupo usando como “datos” los coeficientes estimados por grupo.

Cada uno puede ser informativo por sí mismo y, además, prepara la comprensión del pooling parcial en un modelo multinivel.

2.8.2 ¿Cuándo es más efectivo el modelado multinivel?

El modelado multinivel es más importante cuando está cerca del pooling completo para al menos algunos grupos (p. ej., Lac Qui Parle en la figura citada). En esta situación se permite que las estimaciones varíen por grupo y se estimen con precisión. Como sugiere la referencia a la fórmula vista anteriormente, el pooling es mayor cuando la desviación estándar a nivel grupo es pequeña, esto es, cuando los grupos son similares: \(\sigma_{\alpha}\) pequeño \(\Rightarrow\) mayor pooling. En contraste, si \(\sigma_{\alpha}\) es grande (grupos muy distintos), el enfoque multinivel se aproxima al sin pooling y aporta poco frente a éste.

Esto no contradice la motivación del enfoque como compromiso entre extremos: el estimador multinivel puede ser cercano al pooling completo para grupos con \(n_j\) pequeños y cercano al sin pooling para grupos con \(n_j\) grandes, funcionando bien en ambos casos automáticamente.

2.8.3 Uso de predictores de nivel grupo para hacer más efectivo el pooling parcial

Además de su interés intrínseco, los predictores de nivel grupo reducen la variación no explicada entre grupos y, con ello, disminuyen \(\sigma_{\alpha}\). Esto incrementa la cantidad de pooling del estimador multinivel, obteniendo estimaciones más precisas de los \(\alpha_j\), especialmente cuando \(n_j\) es pequeño. Siguiendo la plantilla de regresión clásica, se procede agregando predictores a ambos niveles y reduciendo la varianza no explicada en cada nivel. (No obstante, puede haber situaciones en que añadir un predictor de nivel grupo aumente la varianza no explicada).

2.8.4 Significancia estadística

No es apropiado usar significancia estadística como criterio para incluir indicadores de grupo en un modelo multinivel. En el ejemplo de radón con interceptos variables y sin predictor de nivel grupo, el promedio \(\mu_{\alpha}\) se estima en \(1.46\) y los interceptos por condado \(\alpha_j\) muestran desviaciones con sus errores estándar (p. ej., país 1 cerca de 1 error estándar, país 2 a más de 4 errores estándar, país 85 a menos de 1). Aun así, se deben incluir todos los grupos: el objetivo no es probar si ciertos condados difieren significativamente del promedio de Minnesota, sino estimar lo mejor posible en cada condado con la incertidumbre adecuada. En vez de umbrales de significancia, se permiten interceptos que varían y se reconoce que la precisión por grupo puede ser limitada.

El mismo principio se extiende a modelos con pendientes variables, estructuras no anidadas, datos discretos, etc. Una vez incluida una fuente de variación, no se usa la significancia para decidir qué indicadores incluir o excluir.

En la práctica, las mayores restricciones para no usar modelos extremadamente elaborados (con todos los coeficientes variando respecto de todos los factores de agrupación) son: ajuste (el software puede fallar con muchos factores de agrupación) y comprensión (interpretar modelos complejos). La función lmer() suele funcionar bien cuando puede, pero puede fallar con estructuras muy complejas; JAGS es más general, pero puede ser lento con muestras grandes o modelos complejos. Por ello, se recomienda empezar simple y construir gradualmente, ganando también comprensión del modelo ajustado.

2.9 Predicción

2.9.1 Repaso de predicción en regresión clásica

En una regresión clásica, la predicción se basa en definir una matriz de predictores \(\tilde{X}\) para nuevas observaciones y calcular el predictor lineal \(\tilde{X}\beta\). Posteriormente se simulan los valores de respuesta añadiendo errores adecuados:

  • Regresión lineal: \(\tilde{y}= \tilde{X}\beta + \tilde{\epsilon}, \quad \tilde{\epsilon}\sim N(0,\sigma^2)\).
  • Regresión logística: \(\Pr(\tilde{y}_i=1)=\operatorname{logit}^{-1}(\tilde{X}_i\beta)\).
  • Logística binomial: \(\tilde{y}_i \sim \operatorname{Binomial}(\tilde{n}_i, \operatorname{logit}^{-1}(\tilde{X}_i\beta))\).
  • Regresión de Poisson: \(\tilde{y}_i \sim \operatorname{Poisson}(\tilde{u}_i e^{\tilde{X}_i\beta})\).

Ejemplo de simulación en R:

congress <- vector ("list", 49)
for (i in 1:49){
  year <- 1896 + 2*(i-1)
  file <- paste ("../ARM_Data/cong3/", year, ".asc", sep="")
  data.year <- matrix (scan (file), byrow=TRUE, ncol=5)
  data.year <- cbind (rep(year, nrow(data.year)), data.year)
  congress[[i]] <- data.year
}
i86 <- (1986-1896)/2 + 1
cong86 <- congress[[i86]]
cong88 <- congress[[i86+1]]
cong90 <- congress[[i86+2]]

v86 <- cong86[,5]/(cong86[,5]+cong86[,6])
bad86 <- cong86[,5]==-9 | cong86[,6]==-9
v86[bad86] <- NA
contested86 <- v86>.1 & v86<.9
inc86 <- cong86[,4]

v88 <- cong88[,5]/(cong88[,5]+cong88[,6])
bad88 <- cong88[,5]==-9 | cong88[,6]==-9
v88[bad88] <- NA
contested88 <- v88>.1 & v88<.9
inc88 <- cong88[,4]

v90 <- cong90[,5]/(cong90[,5]+cong90[,6])
bad90 <- cong90[,5]==-9 | cong90[,6]==-9
v90[bad90] <- NA
contested90 <- v90>.1 & v90<.9
inc90 <- cong90[,4]

## Fitting the model

v86.adjusted <- ifelse (v86<.1, .25, ifelse (v86>.9, .75, v86))
vote.86 <- v86.adjusted[contested88]
incumbency.88 <- inc88[contested88]
vote.88 <- v88[contested88]

library ("arm")
fit.88 <- lm (vote.88 ~ vote.86 + incumbency.88)
display (fit.88)
lm(formula = vote.88 ~ vote.86 + incumbency.88)
              coef.est coef.se
(Intercept)   0.20     0.02   
vote.86       0.58     0.04   
incumbency.88 0.08     0.01   
---
n = 343, k = 3
residual sd = 0.07, R-Squared = 0.88
## Simulation for inferences and predictions of new data points

incumbency.90 <- inc90
vote.88 <- v88
n.tilde <- length (vote.88)
X.tilde <- cbind (rep (1, n.tilde), vote.88, incumbency.90)

n.sims <- 1000
sim.88 <- sim (fit.88, n.sims)
y.tilde <- array (NA, c(n.sims, n.tilde))
for (s in 1:n.sims){
  pred <- X.tilde %*% sim.88@coef[s,]
  ok <- !is.na(pred)
  y.tilde[s,ok] <- rnorm (sum(ok), pred[ok], sim.88@sigma[s])
}

Estas simulaciones permiten obtener predicciones puntuales (medianas, medias) e intervalos predictivos.

2.9.2 Predicción para una nueva observación en un grupo existente

Para el modelo de radón, con predictor de vivienda (\(x_i\)) y predictor de uranio a nivel de condado (\(u_j\)):

\[ \tilde{y} \mid \theta \sim N(\alpha_{26} + \beta \tilde{x}, \sigma_y^2), \]

donde \(\theta\) incluye los parámetros estimados. Ejemplo en R para el condado 26 (Hennepin), con una casa en el primer piso (\(\tilde{x}=1\)):

x.tilde <- 1
sigma.y.hat <- sigma.hat(M2)$sigma$data
coef.hat <- as.matrix(coef(M2)$county)[26, ]
y.tilde <- rnorm(1, coef.hat %*% c(1, x.tilde, u$Uppm[26]), sigma.y.hat)
show(y.tilde)
[1] 2.062633

Simulaciones múltiples:

n.sims <- 1000
coef.hat <- as.matrix(coef(M2)$county)[26, ]
y.tilde <- rnorm(n.sims, coef.hat %*% c(1, x.tilde, u$Uppm[26]), sigma.y.hat)

Cálculo de intervalos y predicciones:

quantile(y.tilde, c(.25, .5, .75)) # intervalo predictivo 50%
      25%       50%       75% 
0.2398081 0.6998920 1.2524308 
unlogged <- exp(y.tilde)
mean(unlogged) # media en escala original
[1] 2.751075

2.9.3 Predicción para una nueva observación en un nuevo grupo

Si se predice para un condado no incluido en los datos, se requiere generar un nuevo término de error de grupo:

\[ \tilde{\alpha} \sim N(\gamma_0 + \gamma_1 \tilde{u}_j, \sigma_\alpha^2). \]

Ejemplo en R, usando el promedio de uranio:

u.tilde <- mean(u$Uppm)
g.0.hat <- fixef(M2)["(Intercept)"]
g.1.hat <- fixef(M2)["u"]
sigma.a.hat <- sigma.hat(M2)$sigma$county

a.tilde <- rnorm(n.sims, g.0.hat + g.1.hat * u.tilde, sigma.a.hat)
y.tilde <- rnorm(n.sims, a.tilde + fixef(M2)["floor"] * x.tilde, sigma.y.hat)

La predicción resultante es más incierta que en un condado ya observado, dado que se introduce incertidumbre adicional por el nuevo término \(\tilde{\alpha}\). El intervalo predictivo para el nuevo condado resulta alrededor de un 3% más ancho que el del condado 26.

2.9.4 Comparación de predicciones dentro de grupo y entre grupos

  • Dentro de un grupo conocido: precisión ≈ \(\pm \sigma_y = \pm 0.76\).
  • Nuevo grupo: precisión ≈ \(\pm \sqrt{\sigma_y^2 + \sigma_\alpha^2} = \pm 0.78\).

La diferencia es pequeña en este caso porque la varianza entre condados (\(\sigma_\alpha^2\)) es baja comparada con la varianza dentro de condados (\(\sigma_y^2\)).

2.10 Aspectos finales

2.10.1 ¿Cuántos grupos se necesitan?

Cuando el número de grupos \(J\) es pequeño, es difícil estimar la variación entre grupos. En este escenario, los modelos multinivel tienden a comportarse de manera similar a un modelo sin pooling, ya que la estimación de \(\sigma_{\alpha}\) suele ser imprecisa y tiende a sobreestimarse, lo que lleva a resultados cercanos al no pooling. Sin embargo, aun así los modelos multinivel no son peores que una regresión sin pooling y pueden resultar más fáciles de interpretar, al permitir incluir indicadores de todos los grupos sin necesidad de elegir una categoría base.

2.10.2 Casos con uno o dos grupos

Con uno o dos grupos, los modelos multinivel se reducen esencialmente a la regresión clásica, salvo que se incorpore información previa de manera explícita. Un ejemplo sería modelar el sexo como un predictor binario en lugar de como un modelo multinivel con dos niveles. Aun en este escenario, los modelos multinivel pueden resultar útiles para realizar predicciones sobre nuevos grupos.

2.10.3 ¿Cuántas observaciones por grupo se necesitan?

Incluso con dos observaciones por grupo es posible ajustar un modelo multinivel. De hecho, puede aceptarse que haya grupos con una sola observación. En esos casos, los interceptos de grupo \(\alpha_j\) no se estimarán con precisión, pero aun así aportan información parcial que permite estimar los coeficientes y parámetros de varianza de los niveles individual y grupal.

2.10.4 Conjuntos de datos más grandes y modelos más complejos

Cuando se dispone de más datos, se justifica añadir más parámetros al modelo. Por ejemplo, un estudio médico podría comenzar con un modelo simple, luego incluir estimaciones separadas para hombres y mujeres, desagregar por otras variables demográficas, regiones, estados, áreas más pequeñas e interacciones. Estas complejidades siempre existen de forma latente, pero en conjuntos de datos pequeños no es posible aprender tanto, y el ajuste de modelos muy complejos puede no ser útil debido a las grandes incertidumbres resultantes.