lavaanEste documento muestra un ejemplo completo de Modelos de
Ecuaciones Estructurales (SEM) usando el paquete
lavaan en R.
SEM se usa cuando queremos:
Un psicólogo organizacional aplicó tres cuestionarios a 300 trabajadores para medir:
La teoría propone que el Apoyo Social y la Autonomía predicen positivamente la Motivación.
Apoyo Social ─────┐
├──► Motivación en el Trabajo
Autonomía ─────┘
| Paquete | Para qué se usa |
|---|---|
lavaan |
Especificación, estimación e índices de ajuste del SEM |
lavaanPlot |
Diagrama del modelo desde un objeto lavaan |
if (!file.exists("DF (1).csv")) {
stop("No encuentro 'DF (1).csv'. Ponlo en la misma carpeta del .Rmd y vuelve a Knit.")
}
BD <- read.csv("DF (1).csv", dec = ",", fileEncoding = "UTF-8-BOM")
dim(BD) # esperado: 300 filas × 30 columnas## [1] 300 30
## [1] "AS1" "AS2" "AS3" "AS4" "AS5" "AS6" "AS7" "AS8" "AS9" "AS10"
## [11] "AT1" "AT2" "AT3" "AT4" "AT5" "AT6" "AT7" "AT8" "AT9" "AT10"
## [21] "ML1" "ML2" "ML3" "ML4" "ML5" "ML6" "ML7" "ML8" "ML9" "ML10"
Se tienen 30 ítems observados, 10 por cada variable latente:
| Prefijo | Variable latente | Rol |
|---|---|---|
AS1–AS10 |
Apoyo Social | Exógena (predictor) |
AT1–AT10 |
Autonomía | Exógena (predictor) |
ML1–ML10 |
Motivación | Endógena (resultado) |
## AS1 AT1 ML1
## Min. :-1.5600 Min. :-2.4600 Min. :-2.02000
## 1st Qu.:-0.4425 1st Qu.:-0.6150 1st Qu.:-0.51250
## Median :-0.0400 Median : 0.0200 Median : 0.01000
## Mean : 0.0114 Mean :-0.0275 Mean : 0.01657
## 3rd Qu.: 0.4925 3rd Qu.: 0.6200 3rd Qu.: 0.57250
## Max. : 2.1300 Max. : 2.3000 Max. : 2.26000
lavaanLa sintaxis de lavaan usa dos operadores esenciales:
=~ (“medido por”): define una latente
a partir de ítems (modelo de medida).~ (“depende de”): define relaciones
tipo regresión (modelo estructural).Modelo <- '
# -------------------------
# Modelo de medida (CFA)
# -------------------------
Apoyo_Social =~ AS1 + AS2 + AS3 + AS4 + AS5 + AS6 + AS7 + AS8 + AS9 + AS10
Autonomia =~ AT1 + AT2 + AT3 + AT4 + AT5 + AT6 + AT7 + AT8 + AT9 + AT10
Motivacion =~ ML1 + ML2 + ML3 + ML4 + ML5 + ML6 + ML7 + ML8 + ML9 + ML10
# -------------------------
# Modelo estructural (SEM)
# -------------------------
Motivacion ~ Apoyo_Social + Autonomia
'=~ dice: “estos ítems son indicadores de
esta latente”.sem() ajusta el modelo (por defecto, ML bajo supuestos
estándar del SEM).
fit <- sem(Modelo, data = BD)
summary(
fit,
standardized = TRUE,
fit.measures = TRUE,
rsquare = TRUE
)## lavaan 0.6-21 ended normally after 122 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 63
##
## Number of observations 300
##
## Model Test User Model:
##
## Test statistic 412.655
## Degrees of freedom 402
## P-value (Chi-square) 0.346
##
## Model Test Baseline Model:
##
## Test statistic 15274.215
## Degrees of freedom 435
## P-value 0.000
##
## User Model versus Baseline Model:
##
## Comparative Fit Index (CFI) 0.999
## Tucker-Lewis Index (TLI) 0.999
##
## Loglikelihood and Information Criteria:
##
## Loglikelihood user model (H0) -3231.243
## Loglikelihood unrestricted model (H1) -3024.915
##
## Akaike (AIC) 6588.485
## Bayesian (BIC) 6821.823
## Sample-size adjusted Bayesian (SABIC) 6622.025
##
## Root Mean Square Error of Approximation:
##
## RMSEA 0.009
## 90 Percent confidence interval - lower 0.000
## 90 Percent confidence interval - upper 0.023
## P-value H_0: RMSEA <= 0.050 1.000
## P-value H_0: RMSEA >= 0.080 0.000
##
## Standardized Root Mean Square Residual:
##
## SRMR 0.018
##
## Parameter Estimates:
##
## Standard errors Standard
## Information Expected
## Information saturated (h1) model Structured
##
## Latent Variables:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## Apoyo_Social =~
## AS1 1.000 0.616 0.894
## AS2 1.217 0.045 27.331 0.000 0.750 0.934
## AS3 1.125 0.042 26.672 0.000 0.693 0.926
## AS4 1.162 0.044 26.204 0.000 0.716 0.920
## AS5 1.300 0.047 27.620 0.000 0.801 0.938
## AS6 1.084 0.043 25.459 0.000 0.668 0.910
## AS7 1.142 0.043 26.808 0.000 0.704 0.928
## AS8 1.349 0.048 27.971 0.000 0.832 0.942
## AS9 0.934 0.039 23.777 0.000 0.576 0.886
## AS10 1.115 0.042 26.586 0.000 0.687 0.925
## Autonomia =~
## AT1 1.000 0.839 0.939
## AT2 0.924 0.029 31.780 0.000 0.776 0.929
## AT3 1.018 0.030 33.561 0.000 0.855 0.941
## AT4 0.803 0.027 30.016 0.000 0.674 0.915
## AT5 0.885 0.027 32.508 0.000 0.743 0.934
## AT6 0.775 0.027 28.468 0.000 0.651 0.901
## AT7 0.978 0.029 33.456 0.000 0.821 0.941
## AT8 0.969 0.030 31.793 0.000 0.813 0.929
## AT9 0.935 0.028 33.083 0.000 0.785 0.938
## AT10 0.882 0.027 32.264 0.000 0.740 0.932
## Motivacion =~
## ML1 1.000 0.759 0.925
## ML2 0.880 0.030 29.023 0.000 0.668 0.919
## ML3 0.858 0.029 29.203 0.000 0.651 0.921
## ML4 0.799 0.031 25.940 0.000 0.607 0.887
## ML5 0.978 0.034 28.828 0.000 0.742 0.917
## ML6 1.129 0.036 31.192 0.000 0.857 0.938
## ML7 1.099 0.034 32.326 0.000 0.834 0.947
## ML8 1.118 0.035 32.192 0.000 0.848 0.946
## ML9 0.983 0.033 30.010 0.000 0.746 0.928
## ML10 0.824 0.030 27.710 0.000 0.625 0.906
##
## Regressions:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## Motivacion ~
## Apoyo_Social 1.560 0.061 25.373 0.000 1.268 1.268
## Autonomia 1.058 0.037 28.763 0.000 1.171 1.171
##
## Covariances:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## Apoyo_Social ~~
## Autonomia -0.344 0.038 -9.017 0.000 -0.665 -0.665
##
## Variances:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## .AS1 0.096 0.008 11.775 0.000 0.096 0.201
## .AS2 0.082 0.007 11.423 0.000 0.082 0.127
## .AS3 0.080 0.007 11.524 0.000 0.080 0.142
## .AS4 0.093 0.008 11.585 0.000 0.093 0.153
## .AS5 0.088 0.008 11.372 0.000 0.088 0.121
## .AS6 0.092 0.008 11.669 0.000 0.092 0.171
## .AS7 0.080 0.007 11.505 0.000 0.080 0.139
## .AS8 0.088 0.008 11.303 0.000 0.088 0.113
## .AS9 0.091 0.008 11.813 0.000 0.091 0.215
## .AS10 0.080 0.007 11.536 0.000 0.080 0.144
## .AT1 0.095 0.008 11.316 0.000 0.095 0.119
## .AT2 0.096 0.008 11.459 0.000 0.096 0.137
## .AT3 0.094 0.008 11.270 0.000 0.094 0.114
## .AT4 0.088 0.008 11.604 0.000 0.088 0.163
## .AT5 0.080 0.007 11.388 0.000 0.080 0.127
## .AT6 0.098 0.008 11.707 0.000 0.098 0.188
## .AT7 0.088 0.008 11.283 0.000 0.088 0.115
## .AT8 0.105 0.009 11.458 0.000 0.105 0.137
## .AT9 0.084 0.007 11.326 0.000 0.084 0.120
## .AT10 0.082 0.007 11.412 0.000 0.082 0.131
## .ML1 0.097 0.009 11.363 0.000 0.097 0.144
## .ML2 0.082 0.007 11.439 0.000 0.082 0.155
## .ML3 0.076 0.007 11.419 0.000 0.076 0.152
## .ML4 0.100 0.009 11.703 0.000 0.100 0.214
## .ML5 0.104 0.009 11.459 0.000 0.104 0.158
## .ML6 0.100 0.009 11.156 0.000 0.100 0.120
## .ML7 0.080 0.007 10.955 0.000 0.080 0.103
## .ML8 0.085 0.008 10.981 0.000 0.085 0.105
## .ML9 0.089 0.008 11.323 0.000 0.089 0.138
## .ML10 0.085 0.007 11.566 0.000 0.085 0.179
## Apoyo_Social 0.380 0.038 9.971 0.000 1.000 1.000
## Autonomia 0.705 0.065 10.857 0.000 1.000 1.000
## .Motivacion -0.001 0.003 -0.426 0.670 -0.002 -0.002
##
## R-Square:
## Estimate
## AS1 0.799
## AS2 0.873
## AS3 0.858
## AS4 0.847
## AS5 0.879
## AS6 0.829
## AS7 0.861
## AS8 0.887
## AS9 0.785
## AS10 0.856
## AT1 0.881
## AT2 0.863
## AT3 0.886
## AT4 0.837
## AT5 0.873
## AT6 0.812
## AT7 0.885
## AT8 0.863
## AT9 0.880
## AT10 0.869
## ML1 0.856
## ML2 0.845
## ML3 0.848
## ML4 0.786
## ML5 0.842
## ML6 0.880
## ML7 0.897
## ML8 0.895
## ML9 0.862
## ML10 0.821
## Motivacion NA
Las cargas estandarizadas dicen “qué tan fuerte” es la relación
ítem–latente.
≥ 0.70 suele considerarse fuerte (depende del
contexto).
cargas <- standardizedSolution(fit)
tabla_cargas <- subset(cargas, op == "=~")[, c("lhs", "rhs", "est.std", "pvalue")]
tabla_cargasAquí vemos si Apoyo Social y Autonomía tienen efecto sobre Motivación.
efs <- standardizedSolution(fit)
tabla_reg <- subset(efs, op == "~")[, c("lhs", "rhs", "est.std", "pvalue")]
tabla_regMotivacion ~ Apoyo_Social: efecto de Apoyo Social sobre
MotivaciónMotivacion ~ Autonomia: efecto de Autonomía sobre
Motivaciónest.std da la magnitud estandarizada;
pvalue indica significanciaEl ajuste responde: ¿el modelo completo reproduce bien la estructura de covarianzas observada?
fitMeasures(fit, c("chisq", "df", "pvalue",
"cfi", "tli",
"rmsea", "rmsea.ci.lower", "rmsea.ci.upper",
"srmr", "aic", "bic"))## chisq df pvalue cfi tli
## 412.655 402.000 0.346 0.999 0.999
## rmsea rmsea.ci.lower rmsea.ci.upper srmr aic
## 0.009 0.000 0.023 0.018 6588.485
## bic
## 6821.823
| Índice | Qué evalúa | Lectura típica |
|---|---|---|
| χ² (p-value) | discrepancia global | p > 0.05 sugiere buen ajuste (muy sensible a N) |
| CFI / TLI | mejora vs modelo base | ≥ 0.95 suele ser muy buen ajuste |
| RMSEA | error aproximado | ≤ 0.05 excelente; 0.05–0.08 aceptable |
| SRMR | residuo estandarizado promedio | ≤ 0.08 suele ser bueno |
lavaanPlot(
model = fit,
node_options = list(shape = "box", fontname = "Helvetica"),
edge_options = list(color = "grey"),
coefs = TRUE,
stand = TRUE,
sig = 0.05,
stars = c("regress", "latent")
)