> # principles and practice of sem, 5th ed. > # rex b. kline, guilford press, 2023 > > # chapter 21, table 21.2, analysis 1 > # coefficients and effect sizes in basic > # basic growth models for change in neural risk > # processing over ages 14–17 years > > # to avoid the problem that some R packages share the same name > # for different functions, all functions are specified next as > > # package::function > > # which prevents masking, or the default hiding of > # a function with a redundant name from a package used next > > date() [1] "Fri Apr 14 09:23:40 2023" > > v <- R.Version() > print(paste0(v$language, " version ", v$major, ".", + v$minor, " (", v$year, "-", v$month, "-", v$day, ")")) [1] "R version 4.2.3 (2023-03-15)" > > library(lavaan) This is lavaan 0.6-15 lavaan is FREE software! Please report any bugs. > library(semTools) ############################################################################### This is semTools 0.5-6 All users of R (or SEM) are invited to submit functions or ideas for functions. ############################################################################### > > # get citation information > citation("lavaan", auto = TRUE) To cite package ‘lavaan’ in publications use: Rosseel Y, Jorgensen TD, Rockwood N (2023). _lavaan: Latent Variable Analysis_. R package version 0.6-15, . A BibTeX entry for LaTeX users is @Manual{, title = {lavaan: Latent Variable Analysis}, author = {Yves Rosseel and Terrence D. Jorgensen and Nicholas Rockwood}, year = {2023}, note = {R package version 0.6-15}, url = {https://CRAN.R-project.org/package=lavaan}, } > citation("semTools", auto = TRUE) To cite package ‘semTools’ in publications use: Jorgensen TD, Pornprasertmanit S, Schoemann AM, Rosseel Y (2022). _semTools: Useful Tools for Structural Equation Modeling_. R package version 0.5-6, . A BibTeX entry for LaTeX users is @Manual{, title = {semTools: Useful Tools for Structural Equation Modeling}, author = {Terrence D. Jorgensen and Sunthud Pornprasertmanit and Alexander M. Schoemann and Yves Rosseel}, year = {2022}, note = {R package version 0.5-6}, url = {https://CRAN.R-project.org/package=semTools}, } > > # read in summary statistics > kimspoonLower.cor <- ' + 1.00 + .35 1.00 + .28 .35 1.00 + .29 .40 .45 1.00 + .00 .07 .14 .04 1.00 + .00 -.09 -.12 -.10 .26 1.00 ' > > # name the variables and convert to full correlation matrix > kimspoon.cor <- lavaan::getCov(kimspoonLower.cor, names = c("R1", "R2", + "R3", "R4", "abuse", "neglect")) > > # display the correlations > kimspoon.cor R1 R2 R3 R4 abuse neglect R1 1.00 0.35 0.28 0.29 0.00 0.00 R2 0.35 1.00 0.35 0.40 0.07 -0.09 R3 0.28 0.35 1.00 0.45 0.14 -0.12 R4 0.29 0.40 0.45 1.00 0.04 -0.10 abuse 0.00 0.07 0.14 0.04 1.00 0.26 neglect 0.00 -0.09 -0.12 -0.10 0.26 1.00 > > # add the standard deviations and convert to covariances > kimspoon.cov <- lavaan::cor2cov(kimspoon.cor, sds = c(.05,.77,.76,1.15, + 7.75,4.09)) > > # create mean vector > kimspoon.mean = c(.04,.61,.57,.83,7.17,3.03) > > # display the covariances and means > kimspoon.cov R1 R2 R3 R4 abuse neglect R1 0.002500 0.013475 0.010640 0.016675 0.000000 0.000000 R2 0.013475 0.592900 0.204820 0.354200 0.417725 -0.283437 R3 0.010640 0.204820 0.577600 0.393300 0.824600 -0.373008 R4 0.016675 0.354200 0.393300 1.322500 0.356500 -0.470350 abuse 0.000000 0.417725 0.824600 0.356500 60.062500 8.241350 neglect 0.000000 -0.283437 -0.373008 -0.470350 8.241350 16.728100 > kimspoon.mean [1] 0.04 0.61 0.57 0.83 7.17 3.03 > > # for all models, error variance for R1 > # is fixed to equal zero > > # lavaan function growth() automatically fixes > # intercepts of indicators to zero but specifies > # latent growth factor means as free parameters > > # the direct tracing of the constant (delta-1) on > # the latent growth factors are means but are labeled > # as "intercepts" in lavaan output > > # specify all models > > # model 1 > # no growth (intercept only) > > noGrowth.model <- ' + # specify intercept + # fix all loadings to 1.0 + Intercept =~ 1*R1 + 1*R2 + 1*R3 + 1*R4 + # fix error variance for r1 to zero + R1 ~~ 0*R1 ' > > # model 2 > # latent basis growth model > # (curve fitting, level and shape) > # this model is retained > > # maccallum-rmsea for model 2 > # exact fit test > # power at N = 150 > semTools::findRMSEApower(0, .05, 4, 150, .05, 1) [1] 0.136742 > > # minimum N for power at least .90 > semTools::findRMSEAsamplesize(0, .05, 4, .90, .05, 1) [1] 1542 > > basis.model <- ' + Intercept =~ 1*R1 + 1*R2 + 1*R3 + 1*R4 + # specify shape, first and last loadings fixed + Shape =~ 0*R1 + R2 + R3 + 1*R4 + R1 ~~ 0*R1 ' > > # model 3 > # linear growth model > > linear.model <- ' + Intercept =~ 1*R1 + 1*R2 + 1*R3 + 1*R4 + # all loadings fixed to constants + Linear =~ 0*R1 + 1*R2 + 2*R3 + 3*R4 + R1 ~~ 0*R1 ' > > # fit model 1 to data > noGrowth <- lavaan::growth(noGrowth.model, sample.cov = kimspoon.cov, + sample.mean = kimspoon.mean, sample.nobs = 150) > > # fit model 2 to data > basis <- lavaan::growth(basis.model, sample.cov = kimspoon.cov, + sample.mean = kimspoon.mean, sample.nobs = 150) > > # fit model 3 to data > linear <- lavaan::growth(linear.model, sample.cov = kimspoon.cov, + sample.mean = kimspoon.mean, sample.nobs = 150) > > # model chi-squares and chi-square difference tests > anova(noGrowth, basis) Chi-Squared Difference Test Df AIC BIC Chisq Chisq diff RMSEA Df diff Pr(>Chisq) basis 4 610.60 640.71 2.8109 noGrowth 9 865.42 880.47 267.6294 264.82 0.58858 5 < 2.2e-16 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 > anova(basis, linear) Chi-Squared Difference Test Df AIC BIC Chisq Chisq diff RMSEA Df diff Pr(>Chisq) basis 4 610.6 640.71 2.8109 linear 6 638.6 662.69 34.8116 32.001 0.31623 2 1.125e-07 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 > > # model 1 parameter estimates, global fit statistics, > # residuals > # very poor fit > lavaan::summary(noGrowth, fit.measures = TRUE, estimates = FALSE) lavaan 0.6.15 ended normally after 51 iterations Estimator ML Optimization method NLMINB Number of model parameters 5 Number of observations 150 Model Test User Model: Test statistic 267.629 Degrees of freedom 9 P-value (Chi-square) 0.000 Model Test Baseline Model: Test statistic 93.391 Degrees of freedom 6 P-value 0.000 User Model versus Baseline Model: Comparative Fit Index (CFI) 0.000 Tucker-Lewis Index (TLI) -0.973 Loglikelihood and Information Criteria: Loglikelihood user model (H0) -427.710 Loglikelihood unrestricted model (H1) -293.895 Akaike (AIC) 865.420 Bayesian (BIC) 880.473 Sample-size adjusted Bayesian (SABIC) 864.649 Root Mean Square Error of Approximation: RMSEA 0.438 90 Percent confidence interval - lower 0.393 90 Percent confidence interval - upper 0.484 P-value H_0: RMSEA <= 0.050 0.000 P-value H_0: RMSEA >= 0.080 1.000 Standardized Root Mean Square Residual: SRMR 0.452 > lavaan::fitted(noGrowth) $cov R1 R2 R3 R4 R1 0.002 R2 0.002 0.892 R3 0.002 0.002 0.838 R4 0.002 0.002 0.002 1.910 $mean R1 R2 R3 R4 0.04 0.04 0.04 0.04 > lavaan::residuals(noGrowth, type = "standardized") $type [1] "standardized" $cov R1 R2 R3 R4 R1 0.000 R2 3.423 -47.590 R3 2.606 3.999 -42.663 R4 2.964 4.519 4.996 -62.729 $mean R1 R2 R3 R4 0.000 9.290 8.712 8.542 > lavaan::residuals(noGrowth, type = "cor.bollen") $type [1] "cor.bollen" $cov R1 R2 R3 R4 R1 0.000 R2 0.297 0.000 R3 0.226 0.347 0.000 R4 0.254 0.398 0.448 0.000 $mean R1 R2 R3 R4 0.000 0.743 0.700 0.689 > > # model 2 parameter estimates, global fit statistics, > # residuals > # retained model > lavaan::summary(basis, fit.measures = TRUE, rsquare = TRUE) lavaan 0.6.15 ended normally after 67 iterations Estimator ML Optimization method NLMINB Number of model parameters 10 Number of observations 150 Model Test User Model: Test statistic 2.811 Degrees of freedom 4 P-value (Chi-square) 0.590 Model Test Baseline Model: Test statistic 93.391 Degrees of freedom 6 P-value 0.000 User Model versus Baseline Model: Comparative Fit Index (CFI) 1.000 Tucker-Lewis Index (TLI) 1.020 Loglikelihood and Information Criteria: Loglikelihood user model (H0) -295.301 Loglikelihood unrestricted model (H1) -293.895 Akaike (AIC) 610.601 Bayesian (BIC) 640.708 Sample-size adjusted Bayesian (SABIC) 609.059 Root Mean Square Error of Approximation: RMSEA 0.000 90 Percent confidence interval - lower 0.000 90 Percent confidence interval - upper 0.105 P-value H_0: RMSEA <= 0.050 0.739 P-value H_0: RMSEA >= 0.080 0.125 Standardized Root Mean Square Residual: SRMR 0.028 Parameter Estimates: Standard errors Standard Information Expected Information saturated (h1) model Structured Latent Variables: Estimate Std.Err z-value P(>|z|) Intercept =~ R1 1.000 R2 1.000 R3 1.000 R4 1.000 Shape =~ R1 0.000 R2 0.678 0.073 9.278 0.000 R3 0.646 0.071 9.117 0.000 R4 1.000 Covariances: Estimate Std.Err z-value P(>|z|) Intercept ~~ Shape 0.014 0.004 3.741 0.000 Intercepts: Estimate Std.Err z-value P(>|z|) .R1 0.000 .R2 0.000 .R3 0.000 .R4 0.000 Intercept 0.040 0.004 9.831 0.000 Shape 0.817 0.086 9.443 0.000 Variances: Estimate Std.Err z-value P(>|z|) .R1 0.000 .R2 0.359 0.055 6.503 0.000 .R3 0.354 0.053 6.685 0.000 .R4 0.753 0.117 6.424 0.000 Intercept 0.002 0.000 8.660 0.000 Shape 0.487 0.108 4.533 0.000 R-Square: Estimate R1 1.000 R2 0.407 R3 0.388 R4 0.408 > lavaan::standardizedSolution(basis) lhs op rhs est.std se z pvalue ci.lower ci.upper 1 Intercept =~ R1 1.000 0.000 NA NA 1.000 1.000 2 Intercept =~ R2 0.064 0.005 13.350 0 0.055 0.073 3 Intercept =~ R3 0.066 0.005 13.349 0 0.056 0.075 4 Intercept =~ R4 0.044 0.003 13.247 0 0.038 0.051 5 Shape =~ R1 0.000 0.000 NA NA 0.000 0.000 6 Shape =~ R2 0.609 0.056 10.935 0 0.500 0.718 7 Shape =~ R3 0.593 0.056 10.652 0 0.484 0.702 8 Shape =~ R4 0.619 0.056 10.999 0 0.509 0.729 9 R1 ~~ R1 0.000 0.000 NA NA 0.000 0.000 10 R2 ~~ R2 0.593 0.071 8.375 0 0.454 0.732 11 R3 ~~ R3 0.612 0.069 8.850 0 0.477 0.748 12 R4 ~~ R4 0.592 0.072 8.249 0 0.452 0.733 13 Intercept ~~ Intercept 1.000 0.000 NA NA 1.000 1.000 14 Shape ~~ Shape 1.000 0.000 NA NA 1.000 1.000 15 Intercept ~~ Shape 0.410 0.089 4.625 0 0.236 0.584 16 R1 ~1 0.000 0.000 NA NA 0.000 0.000 17 R2 ~1 0.000 0.000 NA NA 0.000 0.000 18 R3 ~1 0.000 0.000 NA NA 0.000 0.000 19 R4 ~1 0.000 0.000 NA NA 0.000 0.000 20 Intercept ~1 0.803 0.094 8.550 0 0.619 0.987 21 Shape ~1 1.170 0.148 7.924 0 0.880 1.459 > > # variance and standard error for Intercept are close to zero, > # so estimates are printed at 5-decimal accuracy, not 3 (default) > print(lavaan::parameterEstimates(basis), nd = 5) lhs op rhs est se z pvalue ci.lower ci.upper 1 Intercept =~ R1 1.00000 0.00000 NA NA 1.00000 1.00000 2 Intercept =~ R2 1.00000 0.00000 NA NA 1.00000 1.00000 3 Intercept =~ R3 1.00000 0.00000 NA NA 1.00000 1.00000 4 Intercept =~ R4 1.00000 0.00000 NA NA 1.00000 1.00000 5 Shape =~ R1 0.00000 0.00000 NA NA 0.00000 0.00000 6 Shape =~ R2 0.67819 0.07309 9.27825 0.00000 0.53493 0.82145 7 Shape =~ R3 0.64606 0.07086 9.11712 0.00000 0.50718 0.78495 8 Shape =~ R4 1.00000 0.00000 NA NA 1.00000 1.00000 9 R1 ~~ R1 0.00000 0.00000 NA NA 0.00000 0.00000 10 R2 ~~ R2 0.35873 0.05516 6.50346 0.00000 0.25062 0.46684 11 R3 ~~ R3 0.35426 0.05300 6.68452 0.00000 0.25039 0.45814 12 R4 ~~ R4 0.75301 0.11723 6.42358 0.00000 0.52325 0.98277 13 Intercept ~~ Intercept 0.00248 0.00029 8.66025 0.00000 0.00192 0.00305 14 Shape ~~ Shape 0.48742 0.10753 4.53278 0.00001 0.27666 0.69818 15 Intercept ~~ Shape 0.01427 0.00381 3.74067 0.00018 0.00679 0.02174 16 R1 ~1 0.00000 0.00000 NA NA 0.00000 0.00000 17 R2 ~1 0.00000 0.00000 NA NA 0.00000 0.00000 18 R3 ~1 0.00000 0.00000 NA NA 0.00000 0.00000 19 R4 ~1 0.00000 0.00000 NA NA 0.00000 0.00000 20 Intercept ~1 0.04000 0.00407 9.83078 0.00000 0.03203 0.04797 21 Shape ~1 0.81652 0.08646 9.44340 0.00000 0.64705 0.98599 > > # implied covariances and means for observed variables > lavaan::fitted(basis) $cov R1 R2 R3 R4 R1 0.002 R2 0.012 0.605 R3 0.012 0.235 0.579 R4 0.017 0.357 0.341 1.271 $mean R1 R2 R3 R4 0.040 0.594 0.568 0.857 > # implied means for latent growth factors > lavaan::lavInspect(basis, add.labels = TRUE, "mean.lv") Intercept Shape 0.040 0.817 > > # residuals > lavaan::residuals(basis, type = "raw") $type [1] "raw" $cov R1 R2 R3 R4 R1 0.000 R2 0.001 -0.016 R3 -0.001 -0.031 -0.005 R4 0.000 -0.005 0.050 0.042 $mean R1 R2 R3 R4 0.000 0.016 0.002 -0.027 > lavaan::residuals(basis, type = "standardized") $type [1] "standardized" $cov R1 R2 R3 R4 R1 0.000 R2 0.622 -0.633 R3 -0.597 -1.193 -0.206 R4 -0.072 -0.134 1.195 0.891 $mean R1 R2 R3 R4 0.000 0.794 0.122 -0.979 > lavaan::residuals(basis, type = "cor.bollen") $type [1] "cor.bollen" $cov R1 R2 R3 R4 R1 0.000 R2 0.036 0.000 R3 -0.029 -0.047 0.000 R4 -0.008 -0.007 0.053 0.000 $mean R1 R2 R3 R4 0.000 0.021 0.003 -0.023 > > # model 3 parameter estimates, global fit statistics, > # residuals > lavaan::summary(linear, fit.measures = TRUE) lavaan 0.6.15 ended normally after 60 iterations Estimator ML Optimization method NLMINB Number of model parameters 8 Number of observations 150 Model Test User Model: Test statistic 34.812 Degrees of freedom 6 P-value (Chi-square) 0.000 Model Test Baseline Model: Test statistic 93.391 Degrees of freedom 6 P-value 0.000 User Model versus Baseline Model: Comparative Fit Index (CFI) 0.670 Tucker-Lewis Index (TLI) 0.670 Loglikelihood and Information Criteria: Loglikelihood user model (H0) -311.301 Loglikelihood unrestricted model (H1) -293.895 Akaike (AIC) 638.602 Bayesian (BIC) 662.687 Sample-size adjusted Bayesian (SABIC) 637.368 Root Mean Square Error of Approximation: RMSEA 0.179 90 Percent confidence interval - lower 0.124 90 Percent confidence interval - upper 0.239 P-value H_0: RMSEA <= 0.050 0.000 P-value H_0: RMSEA >= 0.080 0.998 Standardized Root Mean Square Residual: SRMR 0.122 Parameter Estimates: Standard errors Standard Information Expected Information saturated (h1) model Structured Latent Variables: Estimate Std.Err z-value P(>|z|) Intercept =~ R1 1.000 R2 1.000 R3 1.000 R4 1.000 Linear =~ R1 0.000 R2 1.000 R3 2.000 R4 3.000 Covariances: Estimate Std.Err z-value P(>|z|) Intercept ~~ Linear 0.005 0.001 3.532 0.000 Intercepts: Estimate Std.Err z-value P(>|z|) .R1 0.000 .R2 0.000 .R3 0.000 .R4 0.000 Intercept 0.040 0.004 9.831 0.000 Linear 0.285 0.026 10.879 0.000 Variances: Estimate Std.Err z-value P(>|z|) .R1 0.000 .R2 0.536 0.065 8.298 0.000 .R3 0.314 0.052 5.986 0.000 .R4 0.691 0.117 5.921 0.000 Intercept 0.002 0.000 8.660 0.000 Linear 0.067 0.012 5.343 0.000 > lavaan::fitted(linear) $cov R1 R2 R3 R4 R1 0.002 R2 0.007 0.614 R3 0.012 0.150 0.602 R4 0.017 0.222 0.426 1.322 $mean R1 R2 R3 R4 0.040 0.325 0.610 0.895 > lavaan::residuals(linear, type = "raw") $type [1] "raw" $cov R1 R2 R3 R4 R1 0.000 R2 0.006 -0.025 R3 -0.002 0.053 -0.029 R4 0.000 0.130 -0.036 -0.009 $mean R1 R2 R3 R4 0.000 0.285 -0.040 -0.065 > lavaan::residuals(linear, type = "standardized") $type [1] "standardized" $cov R1 R2 R3 R4 R1 0.000 R2 2.308 -1.084 R3 -0.902 1.375 -1.345 R4 -0.147 2.135 -1.855 -0.203 $mean R1 R2 R3 R4 0.000 5.486 -1.160 -1.314 > lavaan::residuals(linear, type = "cor.bollen") $type [1] "cor.bollen" $cov R1 R2 R3 R4 R1 0.000 R2 0.163 0.000 R3 -0.033 0.103 0.000 R4 -0.005 0.154 -0.028 0.000 $mean R1 R2 R3 R4 0.000 0.372 -0.052 -0.056