5  The Latent Moderated Structural Equations (LMS) and the Quasi Maximum Likelihood (QML) approaches.

The LMS and QML approaches are implemented in modsem. Currently the QML approach is only implented for simpler models with a single endogenous (i.e., dependent) variable. The LMS approach however works on most models, except for models where there is an interaction between two endogenous (i.e., dependent) variables. Both approaches (particularily the LMS approach) are quite computationally intensive, and are thus partly implemented in C++ (using Rcpp and RcppArmadillo). Additionally starting parameters are estimated using the double centering approach (and the means of the observed variables) are used to generate good starting parameters for faster convergence. If you want to see the progress of the estimation process you can use ´verbose = TRUE´.

5.1 A Simple Example

Here you can see an example of the LMS approach for a simple model. By default the summary function calculates fit measures compared to a null model (i.e., the same model without an interaction term).

library(modsem)
m1 <- '
# Outer Model
  X =~ x1
  X =~ x2 + x3
  Z =~ z1 + z2 + z3
  Y =~ y1 + y2 + y3

# Inner model
  Y ~ X + Z
  Y ~ X:Z
'

lms1 <- modsem(m1, oneInt, method = "lms")
summary(lms1)
Estimating null model
EM: Iteration =     1, LogLik =   -17831.87, Change = -17831.875
EM: Iteration =     2, LogLik =   -17831.87, Change =      0.000
Calculating Hessian

----Model Summary------------------------------------------------------

Number of iterations: 32 
Final loglikelihood: -14806.42 

Comparative fit to H0 (no interaction effect)
 D(1) = -6051, p = < 2.22e-16

R-squared:
   Y = 0.596 
R-squared Null-Model (H0):
   Y = 0.395 
R-squared Change:
   Y = 0.201 

----Estimates----------------------------------------------------------

Loadings:
  X: 
   variable   est std.error t.value    p.value ci.lower ci.upper
         x1 1.000        NA      NA         NA       NA       NA
         x2 0.807    0.0120    67.5 < 2.22e-16    0.783    0.830
         x3 0.917    0.0128    71.9 < 2.22e-16    0.892    0.942 
  Z: 
   variable   est std.error t.value    p.value ci.lower ci.upper
         z1 1.000        NA      NA         NA       NA       NA
         z2 0.810    0.0124    65.1 < 2.22e-16    0.786    0.835
         z3 0.881    0.0130    67.7 < 2.22e-16    0.855    0.906 

Regressions: 
  Y: 
   variable   est std.error t.value    p.value ci.lower ci.upper
          X 0.689    0.0302    22.8 < 2.22e-16    0.630    0.748
          Z 0.605    0.0252    24.0 < 2.22e-16    0.556    0.655
        X:Z 0.723    0.0268    27.0 < 2.22e-16    0.670    0.775 

Intercepts: 
   variable   est std.error t.value    p.value ci.lower ci.upper
         x1 1.065   0.00926   115.1 < 2.22e-16    1.047    1.083
         x2 1.249   0.00910   137.3 < 2.22e-16    1.232    1.267
         x3 0.958   0.00924   103.6 < 2.22e-16    0.940    0.976
         z1 1.028   0.02396    42.9 < 2.22e-16    0.981    1.075
         z2 1.219   0.02005    60.8 < 2.22e-16    1.180    1.259
         z3 0.931   0.02144    43.4 < 2.22e-16    0.889    0.973
         y1 1.086   0.02817    38.5 < 2.22e-16    1.030    1.141
         y2 1.259   0.02308    54.6 < 2.22e-16    1.214    1.304
         y3 0.998   0.02567    38.9 < 2.22e-16    0.947    1.048 

Variances:
   variable   est std.error t.value    p.value ci.lower ci.upper
         x1 0.171   0.00541   31.62 < 2.22e-16    0.160    0.182
         x2 0.165   0.00523   31.62 < 2.22e-16    0.155    0.176
         x3 0.171   0.00539   31.62 < 2.22e-16    0.160    0.181
         z1 0.167   0.00898   18.55 < 2.22e-16    0.149    0.184
         z2 0.160   0.00703   22.72 < 2.22e-16    0.146    0.173
         z3 0.158   0.00760   20.83 < 2.22e-16    0.143    0.173
         y1 0.160   0.00884   18.04 < 2.22e-16    0.142    0.177
         y2 0.154   0.00681   22.69 < 2.22e-16    0.141    0.168
         y3 0.164   0.00789   20.73 < 2.22e-16    0.148    0.179
          X 0.913   0.00900  101.53 < 2.22e-16    0.896    0.931
          Z 0.184   0.02221    8.27 < 2.22e-16    0.140    0.227
          Z 1.016   0.01840   55.21 < 2.22e-16    0.980    1.052
          Y 0.991   0.03640   27.22 < 2.22e-16    0.920    1.062 

Here you can see the same example using the QML approach.

qml1 <- modsem(m1, oneInt, method = "qml")
summary(qml1)
Estimating null model
Starting M-step
Calculating Hessian

----Model Summary------------------------------------------------------

Number of iterations: 25 
Final loglikelihood: -17496.81 

Comparative fit to H0 (no interaction effect)
 D(1) = -670, p = < 2.22e-16

R-squared:
   Y = 0.609 
R-squared Null-Model (H0):
   Y = 0.395 
R-squared Change:
   Y = 0.213 

----Estimates----------------------------------------------------------

Loadings:
  X: 
   variable   est std.error t.value    p.value ci.lower ci.upper
         x1 1.000        NA      NA         NA       NA       NA
         x2 0.803    0.0125    64.0 < 2.22e-16    0.778    0.827
         x3 0.914    0.0135    67.8 < 2.22e-16    0.887    0.940 
  Z: 
   variable   est std.error t.value    p.value ci.lower ci.upper
         z1 1.000        NA      NA         NA       NA       NA
         z2 0.810    0.0124    65.2 < 2.22e-16    0.786    0.834
         z3 0.881    0.0130    67.7 < 2.22e-16    0.855    0.906 

Regressions: 
  Y: 
   variable   est std.error t.value    p.value ci.lower ci.upper
          X 0.686    0.0322    21.3 < 2.22e-16    0.622    0.749
          Z 0.577    0.0299    19.3 < 2.22e-16    0.518    0.636
        X:Z 0.706    0.0279    25.3 < 2.22e-16    0.651    0.761 

Intercepts: 
   variable   est std.error t.value    p.value ci.lower ci.upper
         x1 1.038    0.0239    43.5 < 2.22e-16    0.991    1.085
         x2 1.228    0.0199    61.6 < 2.22e-16    1.189    1.267
         x3 0.934    0.0222    42.0 < 2.22e-16    0.890    0.977
         z1 1.026    0.0244    42.1 < 2.22e-16    0.978    1.074
         z2 1.217    0.0204    59.7 < 2.22e-16    1.177    1.257
         z3 0.928    0.0218    42.6 < 2.22e-16    0.886    0.971
         y1 1.070    0.0334    32.1 < 2.22e-16    1.005    1.135
         y2 1.247    0.0271    45.9 < 2.22e-16    1.193    1.300
         y3 0.984    0.0303    32.5 < 2.22e-16    0.924    1.043 

Variances:
   variable   est std.error t.value    p.value ci.lower ci.upper
         x1 0.158   0.00871   18.13 < 2.22e-16    0.141    0.175
         x2 0.162   0.00697   23.19 < 2.22e-16    0.148    0.175
         x3 0.165   0.00794   20.80 < 2.22e-16    0.149    0.181
         z1 0.165   0.00902   18.34 < 2.22e-16    0.148    0.183
         z2 0.159   0.00703   22.63 < 2.22e-16    0.145    0.173
         z3 0.158   0.00762   20.72 < 2.22e-16    0.143    0.173
         y1 0.159   0.00888   17.94 < 2.22e-16    0.142    0.177
         y2 0.155   0.00685   22.63 < 2.22e-16    0.142    0.168
         y3 0.164   0.00791   20.69 < 2.22e-16    0.148    0.179
          X 0.984   0.03643   27.00 < 2.22e-16    0.912    1.055
          Z 0.199   0.02431    8.18 2.7693e-16    0.151    0.247
          Z 1.019   0.03780   26.96 < 2.22e-16    0.945    1.093
          Y 0.951   0.03840   24.76 < 2.22e-16    0.875    1.026 

5.2 A more complicated example

Here you can see an example of a more complicated example using the model from the theory of planned behaviour (TPB), where there are two endogenous variables, where there is an interaction between an endogenous and exogenous variable. (note this does not work with the QML approach). For more complicated models, it is recommended that you increase the number of nodes used for numerical integration. By default the number of nodes is set to 16, and can be increased using the nodes argument.

# ATT = Attitude, 
# PBC = Perceived Behavioural Control 
# INT = Intention 
# SN = Subjective Norms
# BEH = Behaviour
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 Relationsships
  INT ~ ATT + SN + PBC
  BEH ~ INT + PBC 
  BEH ~ INT:PBC  
'

lms2 <- modsem(tpb, TPB, method = "lms", nodes = 20)
summary(lms2)
Estimating null model
EM: Iteration =     1, LogLik =   -26393.22, Change = -26393.223
EM: Iteration =     2, LogLik =   -26393.22, Change =      0.000
Calculating Hessian

----Model Summary------------------------------------------------------

Number of iterations: 29 
Final loglikelihood: -23520.44 

Comparative fit to H0 (no interaction effect)
 D(1) = -5746, p = < 2.22e-16

R-squared:
   INT = 0.357 
   BEH = 0.252 
R-squared Null-Model (H0):
   INT = 0.367 
   BEH = 0.210 
R-squared Change:
   INT = -0.00987 
   BEH =  0.04218 

----Estimates----------------------------------------------------------

Loadings:
  PBC: 
   variable   est std.error t.value    p.value ci.lower ci.upper
       pbc1 1.000        NA      NA         NA       NA       NA
       pbc2 0.912    0.0123    73.9 < 2.22e-16    0.888    0.936
       pbc3 0.802    0.0115    69.5 < 2.22e-16    0.779    0.824 
  ATT: 
   variable   est std.error t.value    p.value ci.lower ci.upper
       att1 1.000        NA      NA         NA       NA       NA
       att2 0.878    0.0123    71.6 < 2.22e-16    0.854    0.902
       att3 0.789    0.0119    66.4 < 2.22e-16    0.765    0.812
       att4 0.695    0.0114    61.0 < 2.22e-16    0.672    0.717
       att5 0.887    0.0125    70.9 < 2.22e-16    0.862    0.911 
  SN: 
   variable   est std.error t.value    p.value ci.lower ci.upper
        sn1 1.000        NA      NA         NA       NA       NA
        sn2 0.888    0.0167    53.1 < 2.22e-16    0.855    0.921 

Regressions: 
  INT: 
   variable   est std.error t.value    p.value ci.lower ci.upper
        PBC 0.214    0.0276    7.77 7.6879e-15    0.160    0.268
        ATT 0.215    0.0257    8.39 < 2.22e-16    0.165    0.266
         SN 0.178    0.0272    6.55 5.7083e-11    0.125    0.231 
  BEH: 
   variable   est std.error t.value    p.value ci.lower ci.upper
        PBC 0.231    0.0214   10.83 < 2.22e-16    0.190    0.273
        INT 0.189    0.0238    7.95 1.9337e-15    0.142    0.236
    PBC:INT 0.206    0.0178   11.59 < 2.22e-16    0.171    0.241 

Intercepts: 
   variable   est std.error t.value    p.value ci.lower ci.upper
       pbc1 0.988   0.00867   114.0 < 2.22e-16    0.971    1.005
       pbc2 0.976   0.00910   107.3 < 2.22e-16    0.958    0.994
       pbc3 0.983   0.00886   111.0 < 2.22e-16    0.966    1.001
       att1 1.011   0.01858    54.4 < 2.22e-16    0.974    1.047
       att2 1.004   0.01663    60.4 < 2.22e-16    0.972    1.037
       att3 1.014   0.01557    65.1 < 2.22e-16    0.983    1.044
       att4 0.997   0.01440    69.2 < 2.22e-16    0.968    1.025
       att5 0.989   0.01689    58.6 < 2.22e-16    0.956    1.023
        sn1 1.001   0.01858    53.9 < 2.22e-16    0.965    1.038
        sn2 1.007   0.01675    60.1 < 2.22e-16    0.974    1.039
       int1 1.012   0.01872    54.1 < 2.22e-16    0.975    1.049
       int2 1.011   0.01752    57.7 < 2.22e-16    0.976    1.045
       int3 1.004   0.01616    62.1 < 2.22e-16    0.972    1.035
         b1 0.999   0.01997    50.0 < 2.22e-16    0.960    1.038
         b2 1.017   0.01865    54.6 < 2.22e-16    0.981    1.054 

Variances:
   variable   est std.error t.value    p.value ci.lower ci.upper
       pbc1 0.150   0.00475   31.62 < 2.22e-16    0.141    0.160
       pbc2 0.165   0.00523   31.62 < 2.22e-16    0.155    0.176
       pbc3 0.157   0.00496   31.62 < 2.22e-16    0.147    0.167
       att1 0.167   0.00709   23.56 < 2.22e-16    0.153    0.181
       att2 0.150   0.00606   24.76 < 2.22e-16    0.138    0.162
       att3 0.159   0.00603   26.42 < 2.22e-16    0.148    0.171
       att4 0.162   0.00586   27.69 < 2.22e-16    0.151    0.174
       att5 0.159   0.00636   24.97 < 2.22e-16    0.146    0.171
        sn1 0.178   0.01447   12.28 < 2.22e-16    0.149    0.206
        sn2 0.157   0.01162   13.49 < 2.22e-16    0.134    0.179
       int1 0.157   0.00865   18.12 < 2.22e-16    0.140    0.174
       int2 0.160   0.00785   20.41 < 2.22e-16    0.145    0.176
       int3 0.168   0.00712   23.56 < 2.22e-16    0.154    0.182
         b1 0.186   0.01811   10.27 < 2.22e-16    0.150    0.221
         b2 0.135   0.01636    8.25 < 2.22e-16    0.103    0.167
        PBC 0.913   0.00849  107.53 < 2.22e-16    0.896    0.929
        ATT 0.643   0.01734   37.08 < 2.22e-16    0.609    0.677
         SN 0.643   0.01804   35.65 < 2.22e-16    0.608    0.679
        ATT 0.977   0.01374   71.07 < 2.22e-16    0.950    1.004
         SN 0.608   0.01789   33.97 < 2.22e-16    0.573    0.643
         SN 0.966   0.01468   65.85 < 2.22e-16    0.938    0.995
        INT 0.492   0.01988   24.74 < 2.22e-16    0.453    0.531
        BEH 0.455   0.02241   20.32 < 2.22e-16    0.411    0.499