modsem_pi()
is a function for estimating interaction effects between latent variables,
in structural equation models (SEMs), using product indicators.
Methods for estimating interaction effects in SEMs can basically be split into
two frameworks:
1. Product Indicator based approaches ("dblcent"
, "rca"
, "uca"
,
"ca"
, "pind"
), and
2. Distributionally based approaches ("lms"
, "qml"
).
modsem_pi()
is essentially a fancy wrapper for lavaan::sem()
which generates the
necessary syntax and variables for the estimation of models with latent product indicators.
Use default_settings_pi()
to get the default settings for the different methods.
Usage
modsem_pi(
model.syntax = NULL,
data = NULL,
method = "dblcent",
match = NULL,
standardize.data = FALSE,
center.data = FALSE,
first.loading.fixed = TRUE,
center.before = NULL,
center.after = NULL,
residuals.prods = NULL,
residual.cov.syntax = NULL,
constrained.prod.mean = NULL,
constrained.loadings = NULL,
constrained.var = NULL,
constrained.res.cov.method = NULL,
auto.scale = "none",
auto.center = "none",
estimator = "ML",
group = NULL,
run = TRUE,
suppress.warnings.lavaan = FALSE,
...
)
Arguments
- model.syntax
lavaan
syntax- data
dataframe
- method
method to use:
"rca"
= residual centering approach (passed tolavaan
),"uca"
= unconstrained approach (passed tolavaan
),"dblcent"
= double centering approach (passed tolavaan
),"pind"
= prod ind approach, with no constraints or centering (passed tolavaan
),"custom"
= use parameters specified in the function call (passed tolavaan
)- match
should the product indicators be created by using the match-strategy
- standardize.data
should data be scaled before fitting model
- center.data
should data be centered before fitting model
- first.loading.fixed
Should the first factor loading in the latent product be fixed to one?
- center.before
should indicators in products be centered before computing products (overwritten by
method
, ifmethod != NULL
)- center.after
should indicator products be centered after they have been computed?
- residuals.prods
should indicator products be centered using residuals (overwritten by
method
, ifmethod != NULL
)- residual.cov.syntax
should syntax for residual covariances be produced (overwritten by
method
, ifmethod != NULL
)- constrained.prod.mean
should syntax for product mean be produced (overwritten by
method
, ifmethod != NULL
)- constrained.loadings
should syntax for constrained loadings be produced (overwritten by
method
, ifmethod != NULL
)- constrained.var
should syntax for constrained variances be produced (overwritten by
method
, ifmethod != NULL
)- constrained.res.cov.method
method for constraining residual covariances
- auto.scale
methods which should be scaled automatically (usually not useful)
- auto.center
methods which should be centered automatically (usually not useful)
- estimator
estimator to use in
lavaan
- group
group variable for multigroup analysis
- run
should the model be run via
lavaan
, ifFALSE
only modified syntax and data is returned- suppress.warnings.lavaan
should warnings from
lavaan
be suppressed?- ...
arguments passed to other functions, e.g.,
lavaan
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_pi(m1, oneInt)
summary(est1)
#> modsem (version 1.0.4, approach = dblcent):
#> lavaan 0.6-19 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
est1Constrained <- modsem_pi(m1, oneInt, method = "ca")
summary(est1Constrained)
} # }
# 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)
# Covariances
ATT ~~ SN + PBC
PBC ~~ SN
# Causal Relationships
INT ~ ATT + SN + PBC
BEH ~ INT + PBC
BEH ~ INT:PBC
'
# Double centering approach
estTpb <- modsem_pi(tpb, data = TPB)
summary(estTpb)
#> modsem (version 1.0.4, approach = dblcent):
#> lavaan 0.6-19 ended normally after 169 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.172 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|)
#> ATT ~~
#> SN 0.629 0.029 21.977 0.000
#> PBC 0.678 0.029 23.721 0.000
#> SN ~~
#> PBC 0.678 0.029 23.338 0.000
#> .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 ~~
#> INTPBC 0.086 0.024 3.519 0.000
#> SN ~~
#> 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
estTpbConstrained <- modsem_pi(tpb, data = TPB, method = "ca")
summary(estTpbConstrained)
} # }