non-centered interaction terms (LMS and QML)
meanstructure_lms_qml.Rmd
Non-centered interaction terms
Using the LMS and QML approaches it is possible to estimate interaction terms where the means of the latent variables are not centered (i.e., they have non-zero means).
Here we can see an example using the TPB
dataset:
tpb <- '
# Outer Model (Based on Hagger et al., 2007)
ATT =~ att1 + att2 + att3 + att4 + att5
SN =~ sn1 + sn2
PBC =~ pbc1 + pbc2 + pbc3
INT =~ int1 + int2 + int3
BEH =~ b1 + b2
# Inner Model (Based on Steinmetz et al., 2011)
INT ~ ATT + SN + PBC
BEH ~ INT + PBC
BEH ~ INT:PBC
# Adding Latent Intercepts
INT ~ 1
BEH ~ 1
PBC ~ 1
SN ~ 1
ATT ~ 1
'
est <- modsem(tpb, TPB, method = "lms", nodes = 32)
summary(est)
#>
#> modsem (1.0.13) ended normally after 46 iterations
#>
#> Estimator LMS
#> Optimization method EMA-NLMINB
#> Number of model parameters 54
#>
#> Number of observations 2000
#>
#> Loglikelihood and Information Criteria:
#> Loglikelihood -26326.02
#> Akaike (AIC) 52760.05
#> Bayesian (BIC) 53062.49
#>
#> Numerical Integration:
#> Points of integration (per dim) 32
#> Dimensions 1
#> Total points of integration 32
#>
#> Fit Measures for Baseline Model (H0):
#> Standard
#> Chi-square 66.27
#> Degrees of Freedom (Chi-square) 82
#> P-value (Chi-square) 0.897
#> RMSEA 0.000
#>
#> Loglikelihood -26393.22
#> Akaike (AIC) 52892.45
#> Bayesian (BIC) 53189.29
#>
#> Comparative Fit to H0 (LRT test):
#> Loglikelihood change 67.20
#> Difference test (D) 134.40
#> Degrees of freedom (D) 1
#> P-value (D) 0.000
#>
#> R-Squared Interaction Model (H1):
#> INT 0.366
#> BEH 0.262
#> R-Squared Baseline Model (H0):
#> INT 0.367
#> BEH 0.210
#> R-Squared Change (H1 - H0):
#> INT -0.001
#> BEH 0.052
#>
#> Parameter Estimates:
#> Coefficients unstandardized
#> Information observed
#> Standard errors standard
#>
#> Latent Variables:
#> Estimate Std.Error z.value P(>|z|)
#> ATT =~
#> att1 1.000
#> att2 0.878 0.012 71.640 0.000
#> att3 0.789 0.012 66.433 0.000
#> att4 0.695 0.011 61.044 0.000
#> att5 0.887 0.013 70.925 0.000
#> SN =~
#> sn1 1.000
#> sn2 0.888 0.017 52.699 0.000
#> PBC =~
#> pbc1 1.000
#> pbc2 0.912 0.013 69.397 0.000
#> pbc3 0.801 0.012 66.025 0.000
#> INT =~
#> int1 1.000
#> int2 0.913 0.015 59.156 0.000
#> int3 0.807 0.014 55.812 0.000
#> BEH =~
#> b1 1.000
#> b2 0.960 0.030 32.040 0.000
#>
#> Regressions:
#> Estimate Std.Error z.value P(>|z|)
#> INT ~
#> ATT 0.213 0.026 8.165 0.000
#> SN 0.176 0.028 6.387 0.000
#> PBC 0.217 0.030 7.347 0.000
#> BEH ~
#> PBC 0.025 0.029 0.877 0.381
#> INT -0.015 0.030 -0.500 0.617
#> INT:PBC 0.205 0.018 11.311 0.000
#>
#> Intercepts:
#> Estimate Std.Error z.value P(>|z|)
#> .pbc2 0.075 0.018 4.238 0.000
#> .pbc3 0.193 0.016 11.724 0.000
#> .att2 0.117 0.017 6.825 0.000
#> .att3 0.217 0.017 13.035 0.000
#> .att4 0.294 0.016 18.455 0.000
#> .att5 0.093 0.017 5.316 0.000
#> .sn2 0.117 0.021 5.610 0.000
#> .int2 0.087 0.020 4.383 0.000
#> .int3 0.187 0.019 9.995 0.000
#> .b2 0.058 0.035 1.660 0.097
#> ATT 1.013 0.024 41.978 0.000
#> SN 1.005 0.024 41.630 0.000
#> PBC 0.997 0.024 42.377 0.000
#> .INT 0.403 0.027 14.697 0.000
#> .BEH 0.784 0.030 26.198 0.000
#>
#> Covariances:
#> Estimate Std.Error z.value P(>|z|)
#> ATT ~~
#> SN 0.629 0.029 21.948 0.000
#> PBC ~~
#> ATT 0.678 0.029 23.717 0.000
#> SN 0.677 0.029 23.337 0.000
#>
#> Variances:
#> Estimate Std.Error z.value P(>|z|)
#> .pbc1 0.144 0.008 18.401 0.000
#> .pbc2 0.160 0.007 21.450 0.000
#> .pbc3 0.155 0.006 23.901 0.000
#> .att1 0.167 0.007 23.536 0.000
#> .att2 0.150 0.006 24.724 0.000
#> .att3 0.159 0.006 26.389 0.000
#> .att4 0.162 0.006 27.656 0.000
#> .att5 0.159 0.006 24.936 0.000
#> .sn1 0.178 0.015 12.095 0.000
#> .sn2 0.157 0.012 13.270 0.000
#> .int1 0.157 0.009 18.111 0.000
#> .int2 0.160 0.008 20.423 0.000
#> .int3 0.168 0.007 23.560 0.000
#> .b1 0.186 0.018 10.163 0.000
#> .b2 0.135 0.016 8.208 0.000
#> ATT 0.998 0.037 27.148 0.000
#> SN 0.987 0.039 25.418 0.000
#> PBC 0.962 0.035 27.248 0.000
#> .INT 0.491 0.020 24.655 0.000
#> .BEH 0.455 0.023 20.214 0.000
Comparing this to the estimates we get when PBC
and
INT
have zero means, we see that the coefficients
BEH~PBC
and BEH~INT
are drastically changed.
This is not a bug, and is a function of the interaction effect rescaling
the coefficients, when not centered at zero. When using the
standardized_estimates
function, or
summary(est, standardized = TRUE)
the interaction effect is
centered, and we can see that the coefficients BEH~PBC
and
BEH~INT
are rescaled once again.
summary(est, standardized = TRUE, centered = TRUE)
#>
#> modsem (1.0.13) ended normally after 46 iterations
#>
#> Estimator LMS
#> Optimization method EMA-NLMINB
#> Number of model parameters 54
#>
#> Number of observations 2000
#>
#> Loglikelihood and Information Criteria:
#> Loglikelihood -26326.02
#> Akaike (AIC) 52760.05
#> Bayesian (BIC) 53062.49
#>
#> Numerical Integration:
#> Points of integration (per dim) 32
#> Dimensions 1
#> Total points of integration 32
#>
#> Fit Measures for Baseline Model (H0):
#> Standard
#> Chi-square 66.27
#> Degrees of Freedom (Chi-square) 82
#> P-value (Chi-square) 0.897
#> RMSEA 0.000
#>
#> Loglikelihood -26393.22
#> Akaike (AIC) 52892.45
#> Bayesian (BIC) 53189.29
#>
#> Comparative Fit to H0 (LRT test):
#> Loglikelihood change 67.20
#> Difference test (D) 134.40
#> Degrees of freedom (D) 1
#> P-value (D) 0.000
#>
#> R-Squared Interaction Model (H1):
#> INT 0.366
#> BEH 0.262
#> R-Squared Baseline Model (H0):
#> INT 0.367
#> BEH 0.210
#> R-Squared Change (H1 - H0):
#> INT -0.001
#> BEH 0.052
#>
#> Parameter Estimates:
#> Coefficients standardized
#> Information observed
#> Standard errors standard
#>
#> Latent Variables:
#> Estimate Std.Error z.value P(>|z|) Std.all Cnt.all
#> ATT =~
#> att1 1.000 0.925 1.000
#> att2 0.878 0.012 71.640 0.000 0.915 0.878
#> att3 0.789 0.012 66.433 0.000 0.892 0.789
#> att4 0.695 0.011 61.044 0.000 0.865 0.695
#> att5 0.887 0.013 70.925 0.000 0.912 0.887
#> SN =~
#> sn1 1.000 0.921 1.000
#> sn2 0.888 0.017 52.699 0.000 0.912 0.888
#> PBC =~
#> pbc1 1.000 0.933 1.000
#> pbc2 0.912 0.013 69.397 0.000 0.913 0.912
#> pbc3 0.801 0.012 66.025 0.000 0.894 0.801
#> INT =~
#> int1 1.000 0.912 1.000
#> int2 0.913 0.015 59.156 0.000 0.895 0.913
#> int3 0.807 0.014 55.812 0.000 0.866 0.807
#> BEH =~
#> b1 1.000 0.877 1.000
#> b2 0.960 0.030 32.040 0.000 0.899 0.960
#>
#> Regressions:
#> Estimate Std.Error z.value P(>|z|) Std.all Cnt.all
#> INT ~
#> ATT 0.213 0.026 8.165 0.000 0.242 0.213
#> SN 0.176 0.028 6.387 0.000 0.199 0.176
#> PBC 0.217 0.030 7.347 0.000 0.242 0.217
#> BEH ~
#> PBC 0.025 0.029 0.877 0.381 0.290 0.233
#> INT -0.015 0.030 -0.500 0.617 0.212 0.189
#> INT:PBC 0.205 0.018 11.311 0.000 0.225 0.205
#>
#> Intercepts:
#> Estimate Std.Error z.value P(>|z|) Std.all Cnt.all
#> .pbc2 0.075 0.018 4.238 0.000
#> .pbc3 0.193 0.016 11.724 0.000
#> .att2 0.117 0.017 6.825 0.000
#> .att3 0.217 0.017 13.035 0.000
#> .att4 0.294 0.016 18.455 0.000
#> .att5 0.093 0.017 5.316 0.000
#> .sn2 0.117 0.021 5.610 0.000
#> .int2 0.087 0.020 4.383 0.000
#> .int3 0.187 0.019 9.995 0.000
#> .b2 0.058 0.035 1.660 0.097
#> ATT 1.013 0.024 41.978 0.000
#> SN 1.005 0.024 41.630 0.000
#> PBC 0.997 0.024 42.377 0.000
#> .INT 0.403 0.027 14.697 0.000
#> .BEH 0.784 0.030 26.198 0.000
#>
#> Covariances:
#> Estimate Std.Error z.value P(>|z|) Std.all Cnt.all
#> ATT ~~
#> SN 0.629 0.029 21.948 0.000 0.634 0.629
#> PBC ~~
#> ATT 0.678 0.029 23.717 0.000 0.692 0.678
#> SN 0.677 0.029 23.337 0.000 0.695 0.677
#>
#> Variances:
#> Estimate Std.Error z.value P(>|z|) Std.all Cnt.all
#> .pbc1 0.144 0.008 18.401 0.000 0.130 0.144
#> .pbc2 0.160 0.007 21.450 0.000 0.166 0.160
#> .pbc3 0.155 0.006 23.901 0.000 0.201 0.155
#> .att1 0.167 0.007 23.536 0.000 0.144 0.167
#> .att2 0.150 0.006 24.724 0.000 0.164 0.150
#> .att3 0.159 0.006 26.389 0.000 0.204 0.159
#> .att4 0.162 0.006 27.656 0.000 0.252 0.162
#> .att5 0.159 0.006 24.936 0.000 0.168 0.159
#> .sn1 0.178 0.015 12.095 0.000 0.153 0.178
#> .sn2 0.157 0.012 13.270 0.000 0.167 0.157
#> .int1 0.157 0.009 18.111 0.000 0.168 0.157
#> .int2 0.160 0.008 20.423 0.000 0.199 0.160
#> .int3 0.168 0.007 23.560 0.000 0.249 0.168
#> .b1 0.186 0.018 10.163 0.000 0.231 0.186
#> .b2 0.135 0.016 8.208 0.000 0.192 0.135
#> ATT 0.998 0.037 27.148 0.000 1.000 0.998
#> SN 0.987 0.039 25.418 0.000 1.000 0.987
#> PBC 0.962 0.035 27.248 0.000 1.000 0.962
#> .INT 0.491 0.020 24.655 0.000 0.634 0.491
#> .BEH 0.455 0.023 20.214 0.000 0.738 0.455
It is also possible to get the centered solution using the
centered_estimates()
function. Note, that
centered_estimates()
removes the mean structure of the
model all together.
centered_estimates(est)
#> lhs op rhs label est std.error z.value p.value ci.lower ci.upper
#> 1 ATT =~ att1 1.000 NA NA NA NA NA
#> 2 ATT =~ att2 0.878 0.012 71.640 0 0.854 0.902
#> 3 ATT =~ att3 0.789 0.012 66.433 0 0.765 0.812
#> 4 ATT =~ att4 0.695 0.011 61.044 0 0.672 0.717
#> 5 ATT =~ att5 0.887 0.013 70.925 0 0.862 0.911
#> 6 SN =~ sn1 1.000 NA NA NA NA NA
#> 7 SN =~ sn2 0.888 0.017 52.699 0 0.855 0.921
#> 8 PBC =~ pbc1 1.000 NA NA NA NA NA
#> 9 PBC =~ pbc2 0.912 0.013 69.397 0 0.886 0.938
#> 10 PBC =~ pbc3 0.801 0.012 66.025 0 0.777 0.824
#> 11 INT =~ int1 1.000 NA NA NA NA NA
#> 12 INT =~ int2 0.913 0.015 59.156 0 0.883 0.943
#> 13 INT =~ int3 0.807 0.014 55.812 0 0.779 0.835
#> 14 BEH =~ b1 1.000 NA NA NA NA NA
#> 15 BEH =~ b2 0.960 0.030 32.040 0 0.901 1.019
#> 16 INT ~ ATT 0.213 0.026 8.165 0 0.162 0.265
#> 17 INT ~ SN 0.176 0.028 6.387 0 0.122 0.231
#> 18 INT ~ PBC 0.217 0.030 7.347 0 0.159 0.275
#> 19 BEH ~ PBC 0.233 0.029 8.032 0 0.176 0.289
#> 20 BEH ~ INT 0.189 0.030 6.297 0 0.130 0.248
#> 21 BEH ~ INT:PBC 0.205 NA NA NA NA NA
#> 22 pbc1 ~~ pbc1 0.144 0.008 18.401 0 0.129 0.160
#> 23 pbc2 ~~ pbc2 0.160 0.007 21.450 0 0.145 0.174
#> 24 pbc3 ~~ pbc3 0.155 0.006 23.901 0 0.142 0.168
#> 25 att1 ~~ att1 0.167 0.007 23.536 0 0.153 0.181
#> 26 att2 ~~ att2 0.150 0.006 24.724 0 0.138 0.162
#> 27 att3 ~~ att3 0.159 0.006 26.389 0 0.148 0.171
#> 28 att4 ~~ att4 0.162 0.006 27.656 0 0.151 0.174
#> 29 att5 ~~ att5 0.159 0.006 24.936 0 0.146 0.171
#> 30 sn1 ~~ sn1 0.178 0.015 12.095 0 0.149 0.207
#> 31 sn2 ~~ sn2 0.157 0.012 13.270 0 0.133 0.180
#> 32 int1 ~~ int1 0.157 0.009 18.111 0 0.140 0.174
#> 33 int2 ~~ int2 0.160 0.008 20.423 0 0.145 0.176
#> 34 int3 ~~ int3 0.168 0.007 23.560 0 0.154 0.182
#> 35 b1 ~~ b1 0.186 0.018 10.163 0 0.150 0.221
#> 36 b2 ~~ b2 0.135 0.016 8.208 0 0.103 0.168
#> 37 ATT ~~ ATT 0.998 0.037 27.148 0 0.926 1.070
#> 38 ATT ~~ SN 0.629 0.029 21.948 0 0.573 0.685
#> 39 SN ~~ SN 0.987 0.039 25.418 0 0.911 1.063
#> 40 PBC ~~ ATT 0.678 0.029 23.717 0 0.622 0.734
#> 41 PBC ~~ SN 0.677 0.029 23.337 0 0.620 0.734
#> 42 PBC ~~ PBC 0.962 0.035 27.248 0 0.892 1.031
#> 43 INT ~~ INT 0.491 0.020 24.655 0 0.452 0.530
#> 44 BEH ~~ BEH 0.455 0.023 20.214 0 0.411 0.500
#> 45 INT:PBC ~~ INT:PBC 0.969 NA NA NA NA NA
#> 46 INT ~~ INT:PBC 0.000 NA NA NA NA NA
#> 47 PBC ~~ INT:PBC 0.000 NA NA NA NA NA