Semana 11: Modelos de Ecuaciones Estructurales (SEM)

Autor/a

Gabriel Sotomayor

0. Objetivos del Práctico

En este práctico, aprenderemos a realizar un Modelo de Ecuaciones Estructurales (SEM), que combina un Análisis Factorial Confirmatorio (AFC) para el modelo de medida y un Análisis de Senderos (Path Analysis) para el modelo estructural. Nos enfocaremos en:

  1. Preparar los datos y realizar una revisión de supuestos en variables ordinales.
  2. Especificar y estimar un modelo SEM con {lavaan} utilizando DWLS.
  3. Evaluar el ajuste global del modelo utilizando diversos índices cuantitativos.
  4. Evaluar el ajuste local mediante la matriz de correlaciones de residuos.
  5. Interpretar tanto el modelo de medida (cargas factoriales) como el modelo estructural (coeficientes path y varianza explicada).
  6. Visualizar el modelo estimado utilizando el paquete {lavaanPlot} de forma clara.

1. Introducción al Ejemplo

Trabajaremos con datos de la Encuesta de Bienestar Social (EBS) 2023 para construir un modelo SEM que busca explicar la sintomatología depresiva (variable latente SM) a partir de la percepción de seguridad ciudadana (variable latente SEG), controlando por diversas covariables sociodemográficas.

Variables Latentes y sus Indicadores:

  • Sintomatología Depresiva (SM): Medida a través de 4 ítems de la escala PHQ-4 (ss7_a a ss7_d en la base de datos).
  • Percepción de Seguridad (SEG): Medida a través de 4 ítems sobre la seguridad que percibe la persona en plazas, de día, de noche, y dentro de su vivienda (h2_a a h2_d).

Para que la lectura del ejemplo sea más clara, la siguiente tabla resume cada variable usada en el modelo.

Nombre en el modelo Variable original Enunciado Categorías
qaut_casen qaut qaut_casen Quintiles de ingreso Casen 1 = I; 2 = II; 3 = III; 4 = IV; 5 = V
glosa_area zona glosa_area Glosa de área 0 = Urbano; 1 = Rural
sg01 sexo sg01 ¿Cuál es su sexo? 0 = Hombre; 1 = Mujer
tramoebs2 edad tramoebs2 Tramos de edad 1 = 18 a 29 años; 2 = 30 a 44 años; 3 = 45 a 59 años; 4 = 60 A 79 años; 5 = 80 años o más
rr4_c maltrato rr4_c Situación: Ha sido tratado(a) injustamente 0 = No; 1 = Sí
a12 social a12 ¿Qué tan satisfecho(a) está con sus relaciones pers. con fam., amigos, etc? 1 = Totalmente insatisfecho(a); 2 = Insatisfecho(a); 3 = Indiferente; 4 = Satisfecho(a); 5 = Totalmente satisfecho(a)
ss7_a sm_1 ss7_a Poco interés o placer en hacer cosas 1 = Nunca; 2 = Algunos días; 3 = Más de la mitad de los días; 4 = Casi todos los días
ss7_b sm_2 ss7_b Se ha sentido decaído(a), deprimido(a) o sin esperanzas 1 = Nunca; 2 = Algunos días; 3 = Más de la mitad de los días; 4 = Casi todos los días
ss7_c sm_3 ss7_c Se ha sentido nervioso(a), ansioso(a) o con los nervios de punta  1 = Nunca; 2 = Algunos días; 3 = Más de la mitad de los días; 4 = Casi todos los días
ss7_d sm_4 ss7_d No ha sido capaz de parar o controlar su preocupación 1 = Nunca; 2 = Algunos días; 3 = Más de la mitad de los días; 4 = Casi todos los días
h2_a seg_1 h2_a Cuánta seguridad tiene: Cuando está en plazas,parques o espacios naturales 1 = Nada; 2 = Poca; 3 = Algo; 4 = Bastante; 5 = Mucha
h2_b seg_2 h2_b Cuánta seguridad tiene: Caminando de día por calles o caminos 1 = Nada; 2 = Poca; 3 = Algo; 4 = Bastante; 5 = Mucha
h2_c seg_3 h2_c Cuánta seguridad tiene: Caminando de noche por calles o caminos 1 = Nada; 2 = Poca; 3 = Algo; 4 = Bastante; 5 = Mucha
h2_d seg_4 h2_d Cuánta seguridad tiene: Cuando está dentro de su vivienda o predio 1 = Nada; 2 = Poca; 3 = Algo; 4 = Bastante; 5 = Mucha

2. Carga de Paquetes y Preparación de Datos

Cargamos los paquetes necesarios. {lavaanPlot} será nuestra herramienta para visualizar.

# Cargar paquetes
if (!require("pacman")) install.packages("pacman")
pacman::p_load(haven, lavaan, dplyr, lavaanPlot)

Importamos los datos de la EBS 2023. Puedes descargar el archivo Base de datos EBS 2023.RData desde el sitio del Observatorio Social del Ministerio de Desarrollo Social y guardarlo en tu directorio de trabajo. Al cargarlo se importará el objeto EBS_2023_vp, que luego renombramos como ebs.

# Cargar la base de datos de la EBS 2023
load("Base de datos EBS 2023.RData")

# Seleccionar variables de interés y preparar
ebs <- EBS_2023_vp %>% 
  mutate(
    zona = ifelse(glosa_area == "Rural", 1, 0), # 0 = Urbano (ref), 1 = Rural
    sexo = ifelse(sg01 == 2, 1, 0),             # 0 = Hombre (ref), 1 = Mujer
    qaut = qaut_casen,                          # Quintil de ingresos autónomo Casen
    edad = tramoebs2,                           # Tramos de edad EBS
    maltrato = ifelse(rr4_c == 1, 1, ifelse(rr4_c == 2, 0, NA)), # Tratamiento injusto
    social = ifelse(a12 %in% 1:5, a12, NA),     # Satisfacción relaciones personales
    sm_1 = ifelse(ss7_a %in% 1:4, ss7_a, NA),   # PHQ-4
    sm_2 = ifelse(ss7_b %in% 1:4, ss7_b, NA),
    sm_3 = ifelse(ss7_c %in% 1:4, ss7_c, NA),
    sm_4 = ifelse(ss7_d %in% 1:4, ss7_d, NA),
    seg_1 = ifelse(h2_a %in% 1:5, h2_a, NA),    # Ítems Percepción de Seguridad
    seg_2 = ifelse(h2_b %in% 1:5, h2_b, NA),
    seg_3 = ifelse(h2_c %in% 1:5, h2_c, NA),
    seg_4 = ifelse(h2_d %in% 1:5, h2_d, NA)
  ) %>% 
  select(
    qaut, zona, sexo, edad, maltrato, social,
    sm_1, sm_2, sm_3, sm_4,
    seg_1, seg_2, seg_3, seg_4
  )

3. Comprobación de Supuestos

Realizamos una revisión rápida de las observaciones completas disponibles para el análisis.

datos_modelo_completos <- ebs %>%
  select(qaut, zona, sexo, edad, maltrato, social, 
         sm_1, sm_2, sm_3, sm_4, 
         seg_1, seg_2, seg_3, seg_4) %>%
  na.omit()

nrow(datos_modelo_completos)
[1] 10799

Como los indicadores de las variables latentes son ordinales tipo Likert, usaremos el estimador DWLS (Diagonally Weighted Least Squares) en lavaan, que trabaja con correlaciones policóricas subyacentes para este tipo de indicadores.


4. Especificación y Estimación del Modelo SEM

Especificamos el modelo SEM, combinando el modelo de medida y el estructural.

Sintaxis lavaan Comando
~ Regresión (VD ~ VI1 + VI2…)
~~ (Co)varianza
=~ Factor es medido por (variables latentes)
:= Parámetro Definido (ej. efectos indirectos)
etiqueta* Etiquetar un parámetro

Fijaremos como ordinales (ordered) únicamente los indicadores de nuestras variables latentes.

# Especificar el modelo SEM completo
mod_sem_spec <- '
  # 1. Modelo de Medida
  SM  =~ sm_1 + sm_2 + sm_3 + sm_4
  SEG =~ seg_1 + seg_2 + seg_3 + seg_4

  # 2. Modelo Estructural
  SM ~ qaut + zona + sexo + edad + SEG + maltrato + social
'

# Ajustar el modelo SEM con estimador DWLS
ajus_sem <- sem(mod_sem_spec, 
                data = datos_modelo_completos, 
                estimator = "DWLS",
                ordered = c("sm_1", "sm_2", "sm_3", "sm_4",
                            "seg_1", "seg_2", "seg_3", "seg_4"))

Resumen y Evaluación del Modelo

summary(ajus_sem,
        fit.measures = FALSE,
        standardized = TRUE,
        rsquare = TRUE)
lavaan 0.6-21 ended normally after 22 iterations

  Estimator                                       DWLS
  Optimization method                           NLMINB
  Number of model parameters                        43

  Number of observations                         10799

Model Test User Model:
                                                      
  Test statistic                              2401.398
  Degrees of freedom                                61
  P-value (Unknown)                                 NA

Parameter Estimates:

  Parameterization                               Delta
  Standard errors                           Robust.sem
  Information                                 Expected
  Information saturated (h1) model        Unstructured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  SM =~                                                                 
    sm_1              1.000                               0.811    0.771
    sm_2              1.176    0.012  101.243    0.000    0.954    0.890
    sm_3              1.052    0.010  105.493    0.000    0.853    0.806
    sm_4              0.965    0.011   88.840    0.000    0.783    0.746
  SEG =~                                                                
    seg_1             1.000                               0.893    0.893
    seg_2             1.028    0.005  190.289    0.000    0.918    0.918
    seg_3             0.851    0.006  147.721    0.000    0.759    0.759
    seg_4             0.622    0.008   74.883    0.000    0.555    0.555

Regressions:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  SM ~                                                                  
    qaut             -0.039    0.006   -6.304    0.000   -0.049   -0.065
    zona             -0.087    0.023   -3.836    0.000   -0.107   -0.039
    sexo              0.290    0.017   17.296    0.000    0.357    0.176
    edad             -0.009    0.007   -1.297    0.195   -0.011   -0.013
    SEG              -0.117    0.009  -12.315    0.000   -0.128   -0.128
    maltrato          0.483    0.020   24.745    0.000    0.595    0.254
    social           -0.224    0.011  -20.285    0.000   -0.276   -0.201

Thresholds:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
    sm_1|t1          -1.202    0.070  -17.141    0.000   -1.202   -1.142
    sm_1|t2           0.098    0.070    1.399    0.162    0.098    0.093
    sm_1|t3           0.530    0.070    7.525    0.000    0.530    0.504
    sm_2|t1          -1.088    0.071  -15.218    0.000   -1.088   -1.015
    sm_2|t2           0.165    0.071    2.326    0.020    0.165    0.154
    sm_2|t3           0.633    0.072    8.836    0.000    0.633    0.591
    sm_3|t1          -1.074    0.071  -15.126    0.000   -1.074   -1.015
    sm_3|t2           0.134    0.071    1.892    0.058    0.134    0.126
    sm_3|t3           0.579    0.071    8.156    0.000    0.579    0.547
    sm_4|t1          -0.535    0.075   -7.157    0.000   -0.535   -0.510
    sm_4|t2           0.380    0.075    5.095    0.000    0.380    0.363
    sm_4|t3           0.718    0.075    9.538    0.000    0.718    0.685
    seg_1|t1         -0.653    0.069   -9.432    0.000   -0.653   -0.653
    seg_1|t2          0.161    0.068    2.356    0.018    0.161    0.161
    seg_1|t3          0.812    0.069   11.858    0.000    0.812    0.812
    seg_1|t4          1.905    0.070   27.026    0.000    1.905    1.905
    seg_2|t1         -0.872    0.068  -12.738    0.000   -0.872   -0.872
    seg_2|t2         -0.055    0.067   -0.814    0.416   -0.055   -0.055
    seg_2|t3          0.568    0.067    8.436    0.000    0.568    0.568
    seg_2|t4          1.700    0.069   24.659    0.000    1.700    1.700
    seg_3|t1         -0.025    0.071   -0.356    0.721   -0.025   -0.025
    seg_3|t2          0.662    0.071    9.332    0.000    0.662    0.662
    seg_3|t3          1.171    0.071   16.381    0.000    1.171    1.171
    seg_3|t4          2.054    0.074   27.574    0.000    2.054    2.054
    seg_4|t1         -1.346    0.074  -18.236    0.000   -1.346   -1.346
    seg_4|t2         -0.830    0.071  -11.768    0.000   -0.830   -0.830
    seg_4|t3         -0.312    0.070   -4.477    0.000   -0.312   -0.312
    seg_4|t4          0.934    0.070   13.405    0.000    0.934    0.934

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .sm_1              0.450                               0.450    0.406
   .sm_2              0.239                               0.239    0.208
   .sm_3              0.391                               0.391    0.350
   .sm_4              0.488                               0.488    0.443
   .seg_1             0.203                               0.203    0.203
   .seg_2             0.158                               0.158    0.158
   .seg_3             0.423                               0.423    0.423
   .seg_4             0.692                               0.692    0.692
   .SM                0.539    0.009   61.104    0.000    0.820    0.820
    SEG               0.797    0.005  148.798    0.000    1.000    1.000

R-Square:
                   Estimate
    sm_1              0.594
    sm_2              0.792
    sm_3              0.650
    sm_4              0.557
    seg_1             0.797
    seg_2             0.842
    seg_3             0.577
    seg_4             0.308
    SM                0.180

Interpretación de la Salida de summary():

A. Evaluación del Ajuste Global del Modelo:

  • Test \(\chi^2\): El estadístico robusto es 2401.398 con 61 grados de libertad. Al trabajar con una muestra de gran tamaño (\(N = 10799\)), la prueba de \(\chi^2\) es sensible al tamaño muestral, por lo que conviene complementarla con otros índices descriptivos de ajuste.
  • CFI = 0.986; TLI = 0.994: Ambos valores se leen como evidencia de ajuste comparativo compatible con el modelo propuesto.
  • RMSEA = 0.060 (IC 90%: 0.058 - 0.062): Este valor se interpreta como una aproximación descriptiva al error global de ajuste.

Conclusión de Ajuste Global: En conjunto, los índices CFI, TLI y RMSEA sugieren que la estructura de covarianzas implicada por el modelo es compatible con las relaciones observadas en la muestra. Esta lectura se complementa con la evaluación del ajuste local.

B. Interpretación del Modelo de Medida (Cargas Factoriales Std.all):

  • Factor SM (Sintomatología Depresiva): Las cargas estandarizadas son 0.771, 0.890, 0.806 y 0.746. Los indicadores Likert muestran una relación clara con el factor.
  • Factor SEG (Percepción de Seguridad): Las cargas estandarizadas son 0.893, 0.918, 0.759 y 0.555. Los ítems sobre seguridad caminando de día (seg_2) y plazas/parques (seg_1) tienen mayor peso en la medición del constructo; la seguridad dentro de la vivienda (seg_4) presenta la carga más baja.

C. Interpretación del Modelo Estructural (Regressions Std.all):

  • qaut (Quintil de Ingresos): Beta = -0.065. A mayor quintil de ingresos, se observa una menor sintomatología depresiva, controlando por las demás variables.
  • zona (Rural=1): Beta = -0.039. En las zonas rurales se reporta una sintomatología depresiva levemente menor que en zonas urbanas, una vez controladas las otras covariables.
  • sexo (Mujer=1): Beta = 0.176. Las mujeres muestran una mayor sintomatología depresiva en comparación con los hombres, manteniendo el resto de las variables constantes.
  • edad (Tramos EBS): Beta = -0.013 (p = 0.195). Los tramos de edad no muestran una asociación directa clara con la sintomatología depresiva una vez ajustado el modelo.
  • SEG (Percepción de Seguridad): Beta = -0.128. Una mayor percepción de seguridad ciudadana se asocia con una menor sintomatología depresiva.
  • maltrato (Tratamiento Injusto = 1): Beta = 0.254. Reportar haber sufrido tratamiento injusto o discriminación durante el último año aparece como el predictor positivo de mayor magnitud en este modelo.
  • social (Relaciones Personales): Beta = -0.201. Una mayor satisfacción con las relaciones personales con familiares y amigos se asocia con una menor sintomatología depresiva.

D. Varianza Explicada (\(R^2\)):

  • SM: \(R^2 = 0.180\). El modelo estructural explica el 18.0% de la varianza de la sintomatología depresiva en la muestra analizada.

4.1 Evaluación del Ajuste Local (Matriz de Residuos)

La evaluación global del modelo se complementa con un diagnóstico a nivel local. En el marco de variables de naturaleza ordinal estimadas con DWLS en {lavaan}, extraemos la matriz de residuos de correlación policórica subyacente (accesible a través de la propiedad res.cov del objeto de residuos).

Valores absolutos de correlación residual superiores a \(|0.10|\) se usan como heurístico para alertar sobre áreas localizadas de desajuste.

residuos_list <- lavResiduals(ajus_sem, type = "cor")
residuos_cor <- residuos_list[["res.cov"]]

round(residuos_cor, 3)
        sm_1   sm_2   sm_3   sm_4  seg_1  seg_2  seg_3  seg_4
sm_1   0.000                                                 
sm_2   0.039  0.000                                          
sm_3  -0.049 -0.016  0.000                                   
sm_4  -0.036 -0.043  0.061  0.000                            
seg_1  0.013  0.000 -0.004 -0.008  0.000                     
seg_2  0.019  0.014  0.022  0.012 -0.003  0.000              
seg_3  0.004 -0.007 -0.016  0.006  0.012  0.002  0.000       
seg_4 -0.019 -0.031 -0.019 -0.041  0.001  0.032 -0.083  0.000

Interpretación de los Residuos:

Al analizar la matriz de residuos de correlación policórica, observamos que las discrepancias específicas son pequeñas. El residuo absoluto más alto es 0.083 (entre seg_4 y seg_3). Como ningún par de indicadores excede el límite heurístico de \(|0.10|\), no se observan desajustes locales grandes según este criterio.


5. Visualización del Modelo con lavaan.plot

El paquete {lavaanPlot} nos permite generar diagramas de senderos estilizados e integrados.

# Visualizar el modelo usando lavaanPlot de forma limpia
lavaanPlot(model = ajus_sem, 
           node_options = list(shape = "box", fontname = "Helvetica"),
           edge_options = list(color = "black"),
           coefs = TRUE,           # Mostrar coeficientes
           stand = TRUE,           # Usar la solución estandarizada
           covs = FALSE,           # No graficar covarianzas entre exógenas
           stars = "regress",      # Añadir estrellas de significancia en regresiones
           graph_options = list(rankdir = "LR"))

Interpretación del Gráfico:

  • Modelo de Medida (Derecha): Los factores latentes (SM y SEG) se grafican en óvalos, con flechas directas hacia sus indicadores empíricos observados (rectángulos). Los valores en las flechas representan las cargas factoriales estandarizadas.
  • Modelo Estructural (Izquierda e Intermedio): Las variables exógenas continuas, las recodificadas dicotómicas y el constructo SEG dirigen flechas hacia el factor endógeno SM. Las etiquetas representan los coeficientes path estandarizados y las estrellas reflejan su significancia, permitiendo comparar visualmente las fuerzas predictivas.

6. Conclusión del Práctico

Ajuste global y local. El modelo fue estimado con DWLS por la naturaleza ordinal de los indicadores. Los índices globales principales (CFI = 0.986, TLI = 0.994, RMSEA = 0.060) son compatibles con el modelo propuesto. A nivel local, ningún residuo de correlación absoluta supera el heurístico de \(|0.10|\).

Modelo de medida. Las escalas de sintomatología depresiva (SM) y percepción de seguridad (SEG) quedan representadas por sus indicadores, aunque las cargas no tienen la misma magnitud en todos los ítems.

Modelo estructural. La vivencia de tratos injustos o discriminación en el último año, la satisfacción con las relaciones personales y la percepción de seguridad ciudadana aparecen como predictores relevantes de la sintomatología depresiva. El sistema estructural explica el 18.0% de la varianza de SM.

Nota sobre Inferencia Causal y Modelos Equivalentes (Kline, 2023)

Al trabajar con datos transversales (cross-sectional) de la Encuesta de Bienestar Social (EBS) 2023, la estimación de un coeficiente de trayectoria negativo de SEG sobre SM (Percepción de Seguridad ➡️ Sintomatología Depresiva) se lee como una asociación estadística de coincidencia temporal.

Metodológicamente, esto remite al problema de los Modelos Equivalentes: un modelo alternativo en el cual la Sintomatología Depresiva afecte la Percepción de Seguridad (invirtiendo la dirección de la flecha: SM ➡️ SEG) podría reproducir la misma matriz de varianzas-covarianzas implicada y reportar los mismos estadísticos de ajuste global. El software no puede resolver esta equivalencia por sí solo. La decisión de modelar la seguridad como predictor se apoya en la plausibilidad teórica, pero una defensa causal más fuerte requeriría diseños longitudinales que permitan establecer precedencia temporal.