Este documento ejecuta el script script SEM.R y explica
cada salida y gráfica. Tiene tres objetivos:
Nota: el script original no produce gráficas. Las gráficas de este documento (histogramas, QQ-plots, diagrama de ruta y comparación de errores estándar) se añadieron para facilitar la interpretación. El código original se conserva sin cambios.
# 1. Cargar librerías necesarias
if(!require(lavaan)) install.packages("lavaan", dependencies = TRUE)
if(!require(psych)) install.packages("psych", dependencies = TRUE)
library(lavaan)
library(psych)
# Librerías adicionales solo para las gráficas
library(semPlot)
# 2. Cargar datos integrados en lavaan
datos_bollen <- PoliticalDemocracy
head(datos_bollen)| y1 | y2 | y3 | y4 | y5 | y6 | y7 | y8 | x1 | x2 | x3 |
|---|---|---|---|---|---|---|---|---|---|---|
| 2.50 | 0.000000 | 3.333333 | 0.000000 | 1.250000 | 0.000000 | 3.726360 | 3.333333 | 4.442651 | 3.637586 | 2.557615 |
| 1.25 | 0.000000 | 3.333333 | 0.000000 | 6.250000 | 1.100000 | 6.666666 | 0.736999 | 5.384495 | 5.062595 | 3.568079 |
| 7.50 | 8.800000 | 9.999998 | 9.199991 | 8.750000 | 8.094061 | 9.999998 | 8.211809 | 5.961005 | 6.255750 | 5.224433 |
| 8.90 | 8.800000 | 9.999998 | 9.199991 | 8.907948 | 8.127979 | 9.999998 | 4.615086 | 6.285998 | 7.567863 | 6.267495 |
| 10.00 | 3.333333 | 9.999998 | 6.666666 | 7.500000 | 3.333333 | 9.999998 | 6.666666 | 5.863631 | 6.818924 | 4.573679 |
| 7.50 | 3.333333 | 6.666666 | 6.666666 | 6.250000 | 1.100000 | 6.666666 | 0.368500 | 5.533389 | 5.135798 | 3.892270 |
La base PoliticalDemocracy tiene 75 países en
desarrollo y 11 variables:
| Variable | Significado | Constructo |
|---|---|---|
| x1 | PIB per cápita (1960) | ind60: industrialización 1960 |
| x2 | Consumo de energía per cápita (1960) | ind60 |
| x3 | % de fuerza laboral en la industria (1960) | ind60 |
| y1 | Libertad de prensa (1960) | dem60: democracia 1960 |
| y2 | Libertad de oposición política (1960) | dem60 |
| y3 | Elecciones justas (1960) | dem60 |
| y4 | Efectividad del legislativo electo (1960) | dem60 |
| y5 – y8 | Los mismos cuatro indicadores medidos en 1965 | dem65: democracia 1965 |
variables <- c("x1", "x2", "x3", "y1", "y2", "y3", "y4", "y5", "y6", "y7", "y8")
shapiro_resultados <- sapply(datos_bollen[, variables], function(v) {
test <- shapiro.test(v)
c(W = round(test$statistic, 3), p_value = round(test$p.value, 5))
})
print("Resultados de la prueba de Shapiro-Wilk:")[1] "Resultados de la prueba de Shapiro-Wilk:"
W.W p_value
x1 0.975 0.14543
x2 0.976 0.17151
x3 0.973 0.11450
y1 0.932 0.00056
y2 0.831 0.00000
y3 0.855 0.00000
y4 0.899 0.00002
y5 0.960 0.01788
y6 0.811 0.00000
y7 0.872 0.00000
y8 0.901 0.00002
Cómo leerla. La hipótesis nula (H0) es que la variable sigue una distribución normal. Si p < 0.05, se rechaza la normalidad. El estadístico W vale 1 cuando el ajuste a la normal es perfecto, y valores más bajos indican mayor desviación.
Resultados:
Esto tiene sentido: las variables de democracia son escalas acotadas (de 0 a 10) donde muchos países se acumulan en los extremos (totalmente democráticos o totalmente autoritarios).
[1] "Evaluación de Asimetría y Curtosis:"
| mean | sd | skew | kurtosis | |
|---|---|---|---|---|
| x1 | 5.054384 | 0.7329043 | 0.2539241 | -0.7538511 |
| x2 | 4.792195 | 1.5106644 | -0.3457856 | -0.5708606 |
| x3 | 3.557690 | 1.4057112 | 0.0838115 | -0.9361009 |
| y1 | 5.464667 | 2.6227020 | -0.0914478 | -1.1544702 |
| y2 | 4.256443 | 3.9471276 | 0.3186940 | -1.4672781 |
| y3 | 6.563110 | 3.2808912 | -0.5940263 | -0.7191094 |
| y4 | 4.452533 | 3.3494674 | 0.1177271 | -1.2126786 |
| y5 | 5.136252 | 2.6126022 | -0.2279739 | -0.7782401 |
| y6 | 2.978074 | 3.3727326 | 0.8929756 | -0.4688261 |
| y7 | 6.196264 | 3.2862398 | -0.5533005 | -0.7337422 |
| y8 | 4.043390 | 3.2455927 | 0.4455857 | -0.9614966 |
Cómo leerla. skew es la asimetría y
kurtosis es la curtosis en exceso, que
vale 0 en una normal. Un criterio habitual (Kline; West, Finch y Curran)
considera problemáticos los valores |asimetría| > 2 y |curtosis| >
7. Un criterio más estricto usa |valor| > 1.
Resultados:
Conclusión: la no normalidad no viene de colas pesadas ni de asimetrías extremas. Viene de distribuciones aplanadas o bimodales, con valores agrupados en los extremos de la escala. Ningún valor pasa los umbrales severos (2 y 7), así que la desviación es moderada, pero los indicadores no son normales.
par(mfrow = c(3, 4), mar = c(4, 4, 2.5, 1))
for (v in variables) {
x <- datos_bollen[[v]]
hist(x, freq = FALSE, breaks = 10, col = "#9ecae1", border = "white",
main = paste0(v, " (p S-W = ", round(shapiro.test(x)$p.value, 3), ")"),
xlab = v, ylab = "Densidad")
lines(density(x), col = "#08519c", lwd = 2)
curve(dnorm(x, mean(datos_bollen[[v]]), sd(datos_bollen[[v]])),
add = TRUE, col = "#de2d26", lwd = 2, lty = 2)
}
plot.new()
legend("center", legend = c("Densidad empírica", "Normal teórica"),
col = c("#08519c", "#de2d26"), lty = c(1, 2), lwd = 2, bty = "n")Interpretación de la gráfica. Cada panel compara la forma real de los datos (línea azul continua) con la normal que tendría la misma media y desviación (línea roja discontinua).
par(mfrow = c(3, 4), mar = c(4, 4, 2.5, 1))
for (v in variables) {
qqnorm(datos_bollen[[v]], main = v, pch = 19, col = "#3182bd80",
xlab = "Cuantiles teóricos", ylab = "Cuantiles observados")
qqline(datos_bollen[[v]], col = "#de2d26", lwd = 2)
}Interpretación de la gráfica. Si una variable es normal, sus puntos caen sobre la línea roja.
ML necesita normalidad multivariada, no solo univariada. Como complemento se aplica la prueba de Mardia:
Call: mardia(x = datos_bollen[, variables], plot = TRUE)
Mardia tests of multivariate skew and kurtosis
Use describe(x) the to get univariate tests
n.obs = 75 num.vars = 11
b1p = 26.47 skew = 330.9 with probability <= 0.035
small sample skew = 346.41 with probability <= 0.0083
b2p = 134.57 kurtosis = -2.16 with probability <= 0.031
Interpretación:
Conclusión de la Pregunta 1: los datos violan el supuesto de normalidad multivariada. Por eso conviene comparar la estimación ML clásica con una alternativa robusta (MLR), que corrige los errores estándar y el estadístico ji-cuadrado.
# 4. Definición del Modelo SEM (Bollen, 1989)
modelo_bollen <- '
# Modelo de Medida
ind60 =~ x1 + x2 + x3
dem60 =~ y1 + y2 + y3 + y4
dem65 =~ y5 + y6 + y7 + y8
# Modelo Estructural (Regresiones)
dem60 ~ ind60
dem65 ~ ind60 + dem60
# Covarianzas Residuales entre Indicadores Repetidos
y1 ~~ y5
y2 ~~ y6
y3 ~~ y7
y4 ~~ y8
y2 ~~ y4
y6 ~~ y8
'El modelo tiene tres partes:
=~, “se mide por”):
tres variables latentes, cada una medida por sus indicadores. La primera
carga de cada factor (x1, y1, y5) se fija en 1 para darle escala a la
latente.~, “se regresa
sobre”): la industrialización de 1960 influye en la democracia
de 1960. La democracia de 1965 depende de la industrialización y de la
democracia de 1960 (efecto de estabilidad en el
tiempo).~~):
Grados de libertad: hay 11·12/2 = 66 momentos observados y 31 parámetros libres, así que gl = 35. El modelo está sobreidentificado y se puede evaluar su ajuste.
# 5. Estimación Clásica (ML) vs. Estimación Robusta (MLR)
fit_ml <- sem(modelo_bollen, data = datos_bollen, estimator = "ML")
fit_mlr <- sem(modelo_bollen, data = datos_bollen, estimator = "MLR")semPaths(fit_ml, what = "std", whatLabels = "std", layout = "tree2",
rotation = 2, edge.label.cex = 0.85, sizeMan = 6, sizeLat = 9,
nCharNodes = 0, residuals = TRUE, intercepts = FALSE,
edge.color = "black", style = "lisrel", curvePivot = TRUE,
color = list(lat = "#c6dbef", man = "#fff7bc"),
title = FALSE)
title("Diagrama de ruta (coeficientes estandarizados, ML)", line = 2)Interpretación del diagrama:
--- RESUMEN DE AJUSTE GLOBAL (ML CLÁSICO) ---
lavaan 0.7-2 ended normally after 68 iterations
Estimator ML
Optimization method NLMINB
Number of model parameters 31
Number of observations 75
Model Test User Model:
Test statistic 38.125
Degrees of freedom 35
P-value (Chi-square) 0.329
Model Test Baseline Model:
Test statistic 730.654
Degrees of freedom 55
P-value 0.000
User Model versus Baseline Model:
Comparative Fit Index (CFI) 0.995
Tucker-Lewis Index (TLI) 0.993
Loglikelihood and Information Criteria:
Loglikelihood user model (H0) -1547.791
Loglikelihood unrestricted model (H1) -1528.728
Akaike (AIC) 3157.582
Bayesian (BIC) 3229.424
Sample-size adjusted Bayesian (SABIC) 3131.720
Root Mean Square Error of Approximation:
RMSEA 0.035
90 Percent confidence interval - lower 0.000
90 Percent confidence interval - upper 0.092
P-value H_0: RMSEA <= 0.050 0.611
P-value H_0: RMSEA >= 0.080 0.114
Standardized Root Mean Square Residual:
SRMR 0.044
Goodness of Fit Index:
Goodness of Fit Index (GFI) 1.000
90 Percent confidence interval - lower 0.959
90 Percent confidence interval - upper 1.000
Parameter Estimates:
Standard errors Standard
Information Expected
Information saturated (h1) model Structured
Latent Variables:
Estimate Std.Err z-value P(>|z|)
ind60 =~
x1 1.000
x2 2.180 0.139 15.742 0.000
x3 1.819 0.152 11.967 0.000
dem60 =~
y1 1.000
y2 1.257 0.182 6.889 0.000
y3 1.058 0.151 6.987 0.000
y4 1.265 0.145 8.722 0.000
dem65 =~
y5 1.000
y6 1.186 0.169 7.024 0.000
y7 1.280 0.160 8.002 0.000
y8 1.266 0.158 8.007 0.000
Regressions:
Estimate Std.Err z-value P(>|z|)
dem60 ~
ind60 1.483 0.399 3.715 0.000
dem65 ~
ind60 0.572 0.221 2.586 0.010
dem60 0.837 0.098 8.514 0.000
Covariances:
Estimate Std.Err z-value P(>|z|)
.y1 ~~
.y5 0.624 0.358 1.741 0.082
.y2 ~~
.y6 2.153 0.734 2.934 0.003
.y3 ~~
.y7 0.795 0.608 1.308 0.191
.y4 ~~
.y8 0.348 0.442 0.787 0.431
.y2 ~~
.y4 1.313 0.702 1.871 0.061
.y6 ~~
.y8 1.356 0.568 2.386 0.017
Variances:
Estimate Std.Err z-value P(>|z|)
.x1 0.082 0.019 4.184 0.000
.x2 0.120 0.070 1.718 0.086
.x3 0.467 0.090 5.177 0.000
.y1 1.891 0.444 4.256 0.000
.y2 7.373 1.374 5.366 0.000
.y3 5.067 0.952 5.324 0.000
.y4 3.148 0.739 4.261 0.000
.y5 2.351 0.480 4.895 0.000
.y6 4.954 0.914 5.419 0.000
.y7 3.431 0.713 4.814 0.000
.y8 3.254 0.695 4.685 0.000
ind60 0.448 0.087 5.173 0.000
.dem60 3.956 0.921 4.295 0.000
.dem65 0.172 0.215 0.803 0.422
--- RESUMEN DE AJUSTE GLOBAL (ML ROBUSTO) ---
lavaan 0.7-2 ended normally after 68 iterations
Estimator ML
Optimization method NLMINB
Number of model parameters 31
Number of observations 75
Model Test User Model:
Standard Scaled
Test Statistic 38.125 41.401
Degrees of freedom 35 35
P-value (Chi-square) 0.329 0.211
Scaling correction factor 0.921
Yuan-Bentler correction (Mplus variant)
Model Test Baseline Model:
Test statistic 730.654 702.841
Degrees of freedom 55 55
P-value 0.000 0.000
Scaling correction factor 1.040
User Model versus Baseline Model:
Comparative Fit Index (CFI) 0.995 0.990
Tucker-Lewis Index (TLI) 0.993 0.984
Robust Comparative Fit Index (CFI) 0.991
Robust Tucker-Lewis Index (TLI) 0.986
Loglikelihood and Information Criteria:
Loglikelihood user model (H0) -1547.791 -1547.791
Scaling correction factor 1.012
for the MLR correction
Loglikelihood unrestricted model (H1) -1528.728 -1528.728
Scaling correction factor 0.964
for the MLR correction
Akaike (AIC) 3157.582 3157.582
Bayesian (BIC) 3229.424 3229.424
Sample-size adjusted Bayesian (SABIC) 3131.720 3131.720
Root Mean Square Error of Approximation:
RMSEA 0.035 0.049
90 Percent confidence interval - lower 0.000 0.000
90 Percent confidence interval - upper 0.092 0.103
P-value H_0: RMSEA <= 0.050 0.611 0.474
P-value H_0: RMSEA >= 0.080 0.114 0.202
Robust RMSEA 0.047
90 Percent confidence interval - lower 0.000
90 Percent confidence interval - upper 0.097
P-value H_0: Robust RMSEA <= 0.050 0.499
P-value H_0: Robust RMSEA >= 0.080 0.160
Standardized Root Mean Square Residual:
SRMR 0.044 0.044
Goodness of Fit Index:
Goodness of Fit Index (GFI) 1.000
90 Percent confidence interval - lower 0.959
90 Percent confidence interval - upper 1.000
Robust GFI 0.994
90 Percent confidence interval - lower 0.954
90 Percent confidence interval - upper 1.000
Parameter Estimates:
Standard errors Sandwich
Information bread Observed
Observed information based on Hessian
Latent Variables:
Estimate Std.Err z-value P(>|z|)
ind60 =~
x1 1.000
x2 2.180 0.145 15.044 0.000
x3 1.819 0.140 12.950 0.000
dem60 =~
y1 1.000
y2 1.257 0.150 8.392 0.000
y3 1.058 0.130 8.107 0.000
y4 1.265 0.146 8.661 0.000
dem65 =~
y5 1.000
y6 1.186 0.181 6.541 0.000
y7 1.280 0.173 7.415 0.000
y8 1.266 0.189 6.685 0.000
Regressions:
Estimate Std.Err z-value P(>|z|)
dem60 ~
ind60 1.483 0.342 4.332 0.000
dem65 ~
ind60 0.572 0.225 2.546 0.011
dem60 0.837 0.087 9.595 0.000
Covariances:
Estimate Std.Err z-value P(>|z|)
.y1 ~~
.y5 0.624 0.454 1.373 0.170
.y2 ~~
.y6 2.153 0.862 2.497 0.013
.y3 ~~
.y7 0.795 0.615 1.292 0.196
.y4 ~~
.y8 0.348 0.434 0.803 0.422
.y2 ~~
.y4 1.313 0.727 1.807 0.071
.y6 ~~
.y8 1.356 0.738 1.837 0.066
Variances:
Estimate Std.Err z-value P(>|z|)
.x1 0.082 0.019 4.406 0.000
.x2 0.120 0.073 1.652 0.099
.x3 0.467 0.083 5.632 0.000
.y1 1.891 0.477 3.965 0.000
.y2 7.373 1.297 5.686 0.000
.y3 5.067 1.086 4.665 0.000
.y4 3.148 0.793 3.968 0.000
.y5 2.351 0.605 3.885 0.000
.y6 4.954 0.902 5.492 0.000
.y7 3.431 0.622 5.520 0.000
.y8 3.254 0.900 3.615 0.000
ind60 0.448 0.073 6.149 0.000
.dem60 3.956 0.916 4.320 0.000
.dem65 0.172 0.227 0.759 0.448
En la salida de MLR, lavaan escribe
Estimator ML, pero enStandard errorsaparece Sandwich y el ji-cuadrado tiene una columna Scaled con la corrección Yuan-Bentler. Eso confirma que la estimación robusta se aplicó.
ind_ml <- fitMeasures(fit_ml, c("chisq", "df", "pvalue", "cfi", "tli", "rmsea",
"rmsea.ci.lower", "rmsea.ci.upper", "srmr"))
ind_mlr <- fitMeasures(fit_mlr, c("chisq.scaled", "df", "pvalue.scaled", "cfi.robust",
"tli.robust", "rmsea.robust", "rmsea.ci.lower.robust",
"rmsea.ci.upper.robust", "srmr"))
tabla_ajuste <- data.frame(
Indice = c("Chi-cuadrado", "gl", "p-valor", "CFI", "TLI", "RMSEA",
"RMSEA IC90 inf.", "RMSEA IC90 sup.", "SRMR"),
ML = round(as.numeric(ind_ml), 3),
MLR = round(as.numeric(ind_mlr), 3),
Criterio = c("—", "—", "> 0.05", "≥ 0.95", "≥ 0.95", "≤ 0.06",
"—", "≤ 0.10", "≤ 0.08")
)
tabla_ajuste| Indice | ML | MLR | Criterio |
|---|---|---|---|
| Chi-cuadrado | 38.125 | 41.401 | — |
| gl | 35.000 | 35.000 | — |
| p-valor | 0.329 | 0.211 | > 0.05 |
| CFI | 0.995 | 0.991 | ≥ 0.95 |
| TLI | 0.993 | 0.986 | ≥ 0.95 |
| RMSEA | 0.035 | 0.047 | ≤ 0.06 |
| RMSEA IC90 inf. | 0.000 | 0.000 | — |
| RMSEA IC90 sup. | 0.092 | 0.097 | ≤ 0.10 |
| SRMR | 0.044 | 0.044 | ≤ 0.08 |
Interpretación del ajuste global:
| Índice | ML | MLR | Lectura |
|---|---|---|---|
| χ² (gl = 35) | 38.13, p = 0.329 | 41.40, p = 0.211 | No se rechaza H0: el modelo reproduce bien la matriz de covarianzas observada. |
| Factor de escala | — | 0.921 | Es < 1, así que el χ² robusto es mayor (38.13 / 0.921 = 41.40). Esto ocurre con curtosis negativa: ML era algo optimista. |
| CFI / TLI | 0.995 / 0.993 | 0.991 / 0.986 | Ambos superan 0.95: ajuste excelente frente al modelo nulo. |
| RMSEA | 0.035 [0.000, 0.092] | 0.047 [0.000, 0.097] | Está por debajo de 0.05: buen ajuste. El IC es amplio porque la muestra es pequeña (n = 75). |
| SRMR | 0.044 | 0.044 | Es menor que 0.08, así que los residuos son pequeños. No cambia con MLR porque no depende de la distribución. |
Conclusión: el modelo ajusta bien con los dos estimadores. MLR empeora un poco los índices (es más conservador), pero ninguna conclusión cambia.
Otros elementos de la salida:
--- PARÁMETROS Y ERRORES ESTÁNDAR: ML CLÁSICO ---
| lhs | op | rhs | est | se | z | pvalue |
|---|---|---|---|---|---|---|
| ind60 | =~ | x1 | 1.0000000 | 0.0000000 | NA | NA |
| ind60 | =~ | x2 | 2.1803677 | 0.1385093 | 15.741673 | 0.0000000 |
| ind60 | =~ | x3 | 1.8185113 | 0.1519581 | 11.967187 | 0.0000000 |
| dem60 | =~ | y1 | 1.0000000 | 0.0000000 | NA | NA |
| dem60 | =~ | y2 | 1.2567465 | 0.1824396 | 6.888561 | 0.0000000 |
| dem60 | =~ | y3 | 1.0577168 | 0.1513832 | 6.987017 | 0.0000000 |
| dem60 | =~ | y4 | 1.2647865 | 0.1450062 | 8.722292 | 0.0000000 |
| dem65 | =~ | y5 | 1.0000000 | 0.0000000 | NA | NA |
| dem65 | =~ | y6 | 1.1856963 | 0.1688104 | 7.023833 | 0.0000000 |
| dem65 | =~ | y7 | 1.2795122 | 0.1599016 | 8.001871 | 0.0000000 |
| dem65 | =~ | y8 | 1.2659470 | 0.1581111 | 8.006691 | 0.0000000 |
| dem60 | ~ | ind60 | 1.4830005 | 0.3991486 | 3.715409 | 0.0002029 |
| dem65 | ~ | ind60 | 0.5723362 | 0.2213138 | 2.586085 | 0.0097073 |
| dem65 | ~ | dem60 | 0.8373448 | 0.0983510 | 8.513845 | 0.0000000 |
| y1 | ~~ | y5 | 0.6236711 | 0.3583202 | 1.740541 | 0.0817641 |
--- PARÁMETROS Y ERRORES ESTÁNDAR: ML ROBUSTO (MLR) ---
| lhs | op | rhs | est | se | z | pvalue |
|---|---|---|---|---|---|---|
| ind60 | =~ | x1 | 1.0000000 | 0.0000000 | NA | NA |
| ind60 | =~ | x2 | 2.1803677 | 0.1449333 | 15.043938 | 0.0000000 |
| ind60 | =~ | x3 | 1.8185113 | 0.1404273 | 12.949841 | 0.0000000 |
| dem60 | =~ | y1 | 1.0000000 | 0.0000000 | NA | NA |
| dem60 | =~ | y2 | 1.2567465 | 0.1497619 | 8.391631 | 0.0000000 |
| dem60 | =~ | y3 | 1.0577168 | 0.1304706 | 8.106933 | 0.0000000 |
| dem60 | =~ | y4 | 1.2647865 | 0.1460343 | 8.660887 | 0.0000000 |
| dem65 | =~ | y5 | 1.0000000 | 0.0000000 | NA | NA |
| dem65 | =~ | y6 | 1.1856963 | 0.1812746 | 6.540884 | 0.0000000 |
| dem65 | =~ | y7 | 1.2795122 | 0.1725670 | 7.414582 | 0.0000000 |
| dem65 | =~ | y8 | 1.2659470 | 0.1893766 | 6.684813 | 0.0000000 |
| dem60 | ~ | ind60 | 1.4830005 | 0.3423342 | 4.332025 | 0.0000148 |
| dem65 | ~ | ind60 | 0.5723362 | 0.2247623 | 2.546407 | 0.0108838 |
| dem65 | ~ | dem60 | 0.8373448 | 0.0872734 | 9.594504 | 0.0000000 |
| y1 | ~~ | y5 | 0.6236711 | 0.4543482 | 1.372672 | 0.1698543 |
Cómo leer las tablas. est es la
estimación no estandarizada, se su error estándar,
z = est/se el estadístico de Wald y pvalue
prueba H0: parámetro = 0. Las filas 1, 4 y 8 tienen
se = 0 y z = NA porque son las cargas
fijadas en 1 para escalar cada latente.
Puntos clave:
est es idéntica en ML y
MLR. Era lo esperado: MLR no cambia las estimaciones, solo su
precisión.pe_ml <- parameterEstimates(fit_ml)
pe_mlr <- parameterEstimates(fit_mlr)
comp <- data.frame(param = paste(pe_ml$lhs, pe_ml$op, pe_ml$rhs),
se_ml = pe_ml$se, se_mlr = pe_mlr$se,
p_ml = pe_ml$pvalue, p_mlr = pe_mlr$pvalue)
comp <- subset(comp, se_ml > 0)
comp$ratio <- comp$se_mlr / comp$se_ml
comp <- comp[order(comp$ratio), ]
par(mar = c(4.5, 10, 3, 2))
cols <- ifelse(comp$ratio > 1, "#de2d26", "#3182bd")
barplot(comp$ratio - 1, names.arg = comp$param, horiz = TRUE, las = 1,
col = cols, border = NA, cex.names = 0.75,
xlab = "Cambio relativo del error estándar (SE MLR / SE ML − 1)",
main = "¿Cuánto cambia el error estándar al usar MLR?",
axes = FALSE)
ejes <- seq(-0.3, 0.4, 0.1)
axis(1, at = ejes, labels = paste0(ejes * 100, "%"))
abline(v = 0, lwd = 2)
legend("bottomright", c("MLR mayor (ML subestimaba)", "MLR menor (ML sobreestimaba)"),
fill = c("#de2d26", "#3182bd"), border = NA, bty = "n", cex = 0.85)Interpretación de la gráfica. Cada barra muestra cuánto cambia el error estándar al pasar de ML a MLR.
cambios <- comp[(comp$p_ml < 0.05) != (comp$p_mlr < 0.05),
c("param", "se_ml", "se_mlr", "p_ml", "p_mlr")]
cambios[, -1] <- round(cambios[, -1], 3)
cambios| param | se_ml | se_mlr | p_ml | p_mlr | |
|---|---|---|---|---|---|
| 20 | y6 ~~ y8 | 0.568 | 0.738 | 0.017 | 0.066 |
Parámetros cuya significancia cambia (α = 0.05): la tabla muestra que la covarianza y6 ~~ y8 es significativa con ML (p = 0.017) y deja de serlo con MLR (p = 0.066). Es la consecuencia práctica más importante de ignorar la no normalidad: con ML se habría concluido que existe un efecto de método entre y6 y y8 en 1965, y con la corrección robusta esa evidencia no alcanza.
| lhs | op | rhs | est.std | pvalue |
|---|---|---|---|---|
| ind60 | =~ | x1 | 0.9198529 | 0.0000000 |
| ind60 | =~ | x2 | 0.9730326 | 0.0000000 |
| ind60 | =~ | x3 | 0.8721386 | 0.0000000 |
| dem60 | =~ | y1 | 0.8504259 | 0.0000000 |
| dem60 | =~ | y2 | 0.7171221 | 0.0000000 |
| dem60 | =~ | y3 | 0.7223496 | 0.0000000 |
| dem60 | =~ | y4 | 0.8457095 | 0.0000000 |
| dem65 | =~ | y5 | 0.8080175 | 0.0000000 |
| dem65 | =~ | y6 | 0.7460071 | 0.0000000 |
| dem65 | =~ | y7 | 0.8236734 | 0.0000000 |
| dem65 | =~ | y8 | 0.8278413 | 0.0000000 |
| dem60 | ~ | ind60 | 0.4467130 | 0.0000154 |
| dem65 | ~ | ind60 | 0.1822593 | 0.0096761 |
| dem65 | ~ | dem60 | 0.8852290 | 0.0000000 |
x1 x2 x3 y1 y2 y3 y4 y5 y6 y7 y8 dem60 dem65
0.846 0.947 0.761 0.723 0.514 0.522 0.715 0.653 0.557 0.678 0.685 0.200 0.961
Interpretación:
modelo_efectos <- paste(modelo_bollen, '
dem60 ~ a*ind60
dem65 ~ c*ind60 + b*dem60
indirecto := a*b
total := c + a*b
')
fit_ef <- sem(modelo_efectos, data = datos_bollen, estimator = "MLR")
subset(parameterEstimates(fit_ef, standardized = TRUE), op == ":=",
select = c(lhs, est, se, z, pvalue, std.all))| lhs | est | se | z | pvalue | std.all | |
|---|---|---|---|---|---|---|
| 35 | indirecto | 1.241783 | 0.3404644 | 3.647321 | 2.65e-04 | 0.3954433 |
| 36 | total | 1.814119 | 0.4019225 | 4.513604 | 6.40e-06 | 0.5777026 |
Interpretación. La industrialización afecta a la democracia de 1965 por dos vías: