modsem is a function for estimating interaction effects between latent variables, in structural equation models (SEM's). Methods for estimating interaction effects in SEM's can basically be split into two frameworks: 1. Product Indicator based approaches ("dblcent", "rca", "uca", "ca", "pind"), and 2. Distributionally based approaches ("lms", "qml"). For the product indicator based approaces, modsem() is essentially a just a fancy wrapper for lavaan::sem() which generates the necessary syntax, and variables for the estimation of models with latent product indicators. The distributionally based approaches are implemented in seperately, and are are not estimated using lavaan::sem(), but rather using custom functions (largely) written in C++ for performance reasons. For greater control, it is advised that you use one of the sub-functions (modsem_pi, modsem_da, modsem_mplus) directly, as passing additional arguments to them via modsem() can lead to unexpected behavior.
Arguments
- model.syntax
lavaan syntax
- data
dataframe
- method
method to use: "rca" = residual centering approach (passed to lavaan), "uca" = unconstrained approach (passed to lavaan), "dblcent" = double centering approach (passed to lavaan), "pind" = prod ind approach, with no constraints or centering (passed to lavaan), "lms" = laten model structural equations (not passed to lavaan). "qml" = quasi maximum likelihood estimation of laten model structural equations (not passed to lavaan). "custom" = use parameters specified in the function call (passed to lavaan)
- ...
arguments passed to other functions depending on method (see modsem_pi, modsem_da, and modsem_mplus)
Examples
library(modsem)
# For more examples check README and/or GitHub.
# One interaction
m1 <- '
# Outer Model
X =~ x1 + x2 +x3
Y =~ y1 + y2 + y3
Z =~ z1 + z2 + z3
# Inner model
Y ~ X + Z + X:Z
'
# Double centering approach
est1 <- modsem(m1, oneInt)
summary(est1)
#> modsem:
#> Method = dblcent
#> lavaan 0.6-18 ended normally after 159 iterations
#>
#> Estimator ML
#> Optimization method NLMINB
#> Number of model parameters 60
#>
#> Number of observations 2000
#>
#> Model Test User Model:
#>
#> Test statistic 122.924
#> Degrees of freedom 111
#> P-value (Chi-square) 0.207
#>
#> Parameter Estimates:
#>
#> Standard errors Standard
#> Information Expected
#> Information saturated (h1) model Structured
#>
#> Latent Variables:
#> Estimate Std.Err z-value P(>|z|)
#> X =~
#> x1 1.000
#> x2 0.804 0.013 63.612 0.000
#> x3 0.916 0.014 67.144 0.000
#> Y =~
#> y1 1.000
#> y2 0.798 0.007 107.428 0.000
#> y3 0.899 0.008 112.453 0.000
#> Z =~
#> z1 1.000
#> z2 0.812 0.013 64.763 0.000
#> z3 0.882 0.013 67.014 0.000
#> XZ =~
#> x1z1 1.000
#> x2z1 0.805 0.013 60.636 0.000
#> x3z1 0.877 0.014 62.680 0.000
#> x1z2 0.793 0.013 59.343 0.000
#> x2z2 0.646 0.015 43.672 0.000
#> x3z2 0.706 0.016 44.292 0.000
#> x1z3 0.887 0.014 63.700 0.000
#> x2z3 0.716 0.016 45.645 0.000
#> x3z3 0.781 0.017 45.339 0.000
#>
#> Regressions:
#> Estimate Std.Err z-value P(>|z|)
#> Y ~
#> X 0.675 0.027 25.379 0.000
#> Z 0.561 0.026 21.606 0.000
#> XZ 0.702 0.027 26.360 0.000
#>
#> Covariances:
#> Estimate Std.Err z-value P(>|z|)
#> .x1z1 ~~
#> .x2z2 0.000
#> .x2z3 0.000
#> .x3z2 0.000
#> .x3z3 0.000
#> .x2z1 ~~
#> .x1z2 0.000
#> .x1z2 ~~
#> .x2z3 0.000
#> .x3z1 ~~
#> .x1z2 0.000
#> .x1z2 ~~
#> .x3z3 0.000
#> .x2z1 ~~
#> .x1z3 0.000
#> .x2z2 ~~
#> .x1z3 0.000
#> .x3z1 ~~
#> .x1z3 0.000
#> .x3z2 ~~
#> .x1z3 0.000
#> .x2z1 ~~
#> .x3z2 0.000
#> .x3z3 0.000
#> .x3z1 ~~
#> .x2z2 0.000
#> .x2z2 ~~
#> .x3z3 0.000
#> .x3z1 ~~
#> .x2z3 0.000
#> .x3z2 ~~
#> .x2z3 0.000
#> .x1z1 ~~
#> .x1z2 0.115 0.008 14.802 0.000
#> .x1z3 0.114 0.008 13.947 0.000
#> .x2z1 0.125 0.008 16.095 0.000
#> .x3z1 0.140 0.009 16.135 0.000
#> .x1z2 ~~
#> .x1z3 0.103 0.007 14.675 0.000
#> .x2z2 0.128 0.006 20.850 0.000
#> .x3z2 0.146 0.007 21.243 0.000
#> .x1z3 ~~
#> .x2z3 0.116 0.007 17.818 0.000
#> .x3z3 0.135 0.007 18.335 0.000
#> .x2z1 ~~
#> .x2z2 0.135 0.006 20.905 0.000
#> .x2z3 0.145 0.007 21.145 0.000
#> .x3z1 0.114 0.007 16.058 0.000
#> .x2z2 ~~
#> .x2z3 0.117 0.006 20.419 0.000
#> .x3z2 0.116 0.006 20.586 0.000
#> .x2z3 ~~
#> .x3z3 0.109 0.006 18.059 0.000
#> .x3z1 ~~
#> .x3z2 0.138 0.007 19.331 0.000
#> .x3z3 0.158 0.008 20.269 0.000
#> .x3z2 ~~
#> .x3z3 0.131 0.007 19.958 0.000
#> X ~~
#> Z 0.201 0.024 8.271 0.000
#> XZ 0.016 0.025 0.628 0.530
#> Z ~~
#> XZ 0.062 0.025 2.449 0.014
#>
#> Variances:
#> Estimate Std.Err z-value P(>|z|)
#> .x1 0.160 0.009 17.871 0.000
#> .x2 0.162 0.007 22.969 0.000
#> .x3 0.163 0.008 20.161 0.000
#> .y1 0.159 0.009 17.896 0.000
#> .y2 0.154 0.007 22.640 0.000
#> .y3 0.164 0.008 20.698 0.000
#> .z1 0.168 0.009 18.143 0.000
#> .z2 0.158 0.007 22.264 0.000
#> .z3 0.158 0.008 20.389 0.000
#> .x1z1 0.311 0.014 22.227 0.000
#> .x2z1 0.292 0.011 27.287 0.000
#> .x3z1 0.327 0.012 26.275 0.000
#> .x1z2 0.290 0.011 26.910 0.000
#> .x2z2 0.239 0.008 29.770 0.000
#> .x3z2 0.270 0.009 29.117 0.000
#> .x1z3 0.272 0.012 23.586 0.000
#> .x2z3 0.245 0.009 27.979 0.000
#> .x3z3 0.297 0.011 28.154 0.000
#> X 0.981 0.036 26.895 0.000
#> .Y 0.990 0.038 25.926 0.000
#> Z 1.016 0.038 26.856 0.000
#> XZ 1.045 0.044 24.004 0.000
#>
if (FALSE) { # \dontrun{
# The Constrained Approach
est1_ca <- modsem(m1, oneInt, method = "ca")
summary(est1_ca)
# LMS approach
est1_lms <- modsem(m1, oneInt, method = "lms")
summary(est1_lms)
# QML approach
est1_qml <- modsem(m1, oneInt, method = "qml")
summary(est1_qml)
} # }
# Theory Of Planned Behavior
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
'
# double centering approach
est_tpb <- modsem(tpb, data = TPB)
summary(est_tpb)
#> modsem:
#> Method = dblcent
#> lavaan 0.6-18 ended normally after 171 iterations
#>
#> Estimator ML
#> Optimization method NLMINB
#> Number of model parameters 78
#>
#> Number of observations 2000
#>
#> Model Test User Model:
#>
#> Test statistic 207.615
#> Degrees of freedom 222
#> P-value (Chi-square) 0.747
#>
#> Parameter Estimates:
#>
#> Standard errors Standard
#> Information Expected
#> Information saturated (h1) model Structured
#>
#> Latent Variables:
#> Estimate Std.Err z-value P(>|z|)
#> ATT =~
#> att1 1.000
#> att2 0.878 0.012 71.509 0.000
#> att3 0.789 0.012 66.368 0.000
#> att4 0.695 0.011 61.017 0.000
#> att5 0.887 0.013 70.884 0.000
#> SN =~
#> sn1 1.000
#> sn2 0.889 0.017 52.553 0.000
#> PBC =~
#> pbc1 1.000
#> pbc2 0.912 0.013 69.500 0.000
#> pbc3 0.801 0.012 65.830 0.000
#> INT =~
#> int1 1.000
#> int2 0.914 0.016 58.982 0.000
#> int3 0.808 0.015 55.547 0.000
#> BEH =~
#> b1 1.000
#> b2 0.960 0.030 31.561 0.000
#> INTPBC =~
#> int1pbc1 1.000
#> int2pbc1 0.931 0.015 63.809 0.000
#> int3pbc1 0.774 0.013 60.107 0.000
#> int1pbc2 0.893 0.013 68.173 0.000
#> int2pbc2 0.826 0.017 48.845 0.000
#> int3pbc2 0.690 0.015 45.300 0.000
#> int1pbc3 0.799 0.012 67.008 0.000
#> int2pbc3 0.738 0.015 47.809 0.000
#> int3pbc3 0.622 0.014 45.465 0.000
#>
#> Regressions:
#> Estimate Std.Err z-value P(>|z|)
#> INT ~
#> ATT 0.213 0.026 8.170 0.000
#> SN 0.177 0.028 6.416 0.000
#> PBC 0.217 0.030 7.340 0.000
#> BEH ~
#> INT 0.191 0.024 7.817 0.000
#> PBC 0.230 0.022 10.507 0.000
#> INTPBC 0.204 0.018 11.425 0.000
#>
#> Covariances:
#> Estimate Std.Err z-value P(>|z|)
#> .int1pbc1 ~~
#> .int2pbc2 0.000
#> .int2pbc3 0.000
#> .int3pbc2 0.000
#> .int3pbc3 0.000
#> .int2pbc1 ~~
#> .int1pbc2 0.000
#> .int1pbc2 ~~
#> .int2pbc3 0.000
#> .int3pbc1 ~~
#> .int1pbc2 0.000
#> .int1pbc2 ~~
#> .int3pbc3 0.000
#> .int2pbc1 ~~
#> .int1pbc3 0.000
#> .int2pbc2 ~~
#> .int1pbc3 0.000
#> .int3pbc1 ~~
#> .int1pbc3 0.000
#> .int3pbc2 ~~
#> .int1pbc3 0.000
#> .int2pbc1 ~~
#> .int3pbc2 0.000
#> .int3pbc3 0.000
#> .int3pbc1 ~~
#> .int2pbc2 0.000
#> .int2pbc2 ~~
#> .int3pbc3 0.000
#> .int3pbc1 ~~
#> .int2pbc3 0.000
#> .int3pbc2 ~~
#> .int2pbc3 0.000
#> .int1pbc1 ~~
#> .int1pbc2 0.126 0.009 14.768 0.000
#> .int1pbc3 0.102 0.007 13.794 0.000
#> .int2pbc1 0.104 0.007 14.608 0.000
#> .int3pbc1 0.091 0.006 14.109 0.000
#> .int1pbc2 ~~
#> .int1pbc3 0.095 0.007 13.852 0.000
#> .int2pbc2 0.128 0.007 19.320 0.000
#> .int3pbc2 0.119 0.006 19.402 0.000
#> .int1pbc3 ~~
#> .int2pbc3 0.110 0.006 19.911 0.000
#> .int3pbc3 0.097 0.005 19.415 0.000
#> .int2pbc1 ~~
#> .int2pbc2 0.152 0.008 18.665 0.000
#> .int2pbc3 0.138 0.007 18.779 0.000
#> .int3pbc1 0.082 0.006 13.951 0.000
#> .int2pbc2 ~~
#> .int2pbc3 0.121 0.007 18.361 0.000
#> .int3pbc2 0.104 0.005 19.047 0.000
#> .int2pbc3 ~~
#> .int3pbc3 0.087 0.005 19.180 0.000
#> .int3pbc1 ~~
#> .int3pbc2 0.139 0.007 21.210 0.000
#> .int3pbc3 0.123 0.006 21.059 0.000
#> .int3pbc2 ~~
#> .int3pbc3 0.114 0.005 21.021 0.000
#> ATT ~~
#> SN 0.629 0.029 21.977 0.000
#> PBC 0.678 0.029 23.721 0.000
#> INTPBC 0.086 0.024 3.519 0.000
#> SN ~~
#> PBC 0.678 0.029 23.338 0.000
#> INTPBC 0.055 0.025 2.230 0.026
#> PBC ~~
#> INTPBC 0.087 0.024 3.609 0.000
#>
#> Variances:
#> Estimate Std.Err z-value P(>|z|)
#> .att1 0.167 0.007 23.528 0.000
#> .att2 0.150 0.006 24.693 0.000
#> .att3 0.160 0.006 26.378 0.000
#> .att4 0.163 0.006 27.649 0.000
#> .att5 0.159 0.006 24.930 0.000
#> .sn1 0.178 0.015 12.110 0.000
#> .sn2 0.156 0.012 13.221 0.000
#> .pbc1 0.145 0.008 18.440 0.000
#> .pbc2 0.160 0.007 21.547 0.000
#> .pbc3 0.154 0.007 23.716 0.000
#> .int1 0.158 0.009 18.152 0.000
#> .int2 0.160 0.008 20.345 0.000
#> .int3 0.167 0.007 23.414 0.000
#> .b1 0.186 0.018 10.058 0.000
#> .b2 0.135 0.017 8.080 0.000
#> .int1pbc1 0.266 0.013 20.971 0.000
#> .int2pbc1 0.292 0.012 24.421 0.000
#> .int3pbc1 0.251 0.010 26.305 0.000
#> .int1pbc2 0.290 0.012 24.929 0.000
#> .int2pbc2 0.269 0.010 26.701 0.000
#> .int3pbc2 0.253 0.009 29.445 0.000
#> .int1pbc3 0.223 0.009 24.431 0.000
#> .int2pbc3 0.234 0.008 27.633 0.000
#> .int3pbc3 0.203 0.007 29.288 0.000
#> ATT 0.998 0.037 27.138 0.000
#> SN 0.987 0.039 25.394 0.000
#> PBC 0.962 0.035 27.260 0.000
#> .INT 0.490 0.020 24.638 0.000
#> .BEH 0.455 0.023 20.068 0.000
#> INTPBC 1.020 0.041 24.612 0.000
#>
if (FALSE) { # \dontrun{
# The Constrained Approach
est_tpb_ca <- modsem(tpb, data = TPB, method = "ca")
summary(est_tpb_ca)
# LMS approach
est_tpb_lms <- modsem(tpb, data = TPB, method = "lms")
summary(est_tpb_lms)
# QML approach
est_tpb_qml <- modsem(tpb, data = TPB, method = "qml")
summary(est_tpb_qml)
} # }