Skip to contents

modsem() is a function for estimating interaction effects between latent variables in structural equation models (SEMs). Methods for estimating interaction effects in SEMs can basically be split into two frameworks: 1. Product Indicator-based approaches ("dblcent", "rca", "uca", "ca", "pind") 2. Distributionally based approaches ("lms", "qml").

For the product indicator-based approaches, modsem() is essentially 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 separately and 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.

Usage

modsem(model.syntax = NULL, data = NULL, method = "dblcent", ...)

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" = latent model structural equations (not passed to lavaan), "qml" = quasi maximum likelihood estimation of latent 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 the method (see modsem_pi, modsem_da, and modsem_mplus)

Value

modsem object with class modsem_pi, modsem_da, or 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 (version 1.0.4, approach = dblcent):
#> lavaan 0.6-19 ended normally after 161 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", EFIM.S=1000)
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 (version 1.0.4, approach = dblcent):
#> lavaan 0.6-19 ended normally after 173 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)
} # }