Again, some very rough guide to model respecification:
Look at the “Model test” table first. If the pvalue for the chisq test is significant, the model departs from the data.
To see how much are the data incompatible with the model, see the other fit indices. For an approximately fitting model, CFI and TLI should be >.95, RMSEA < .06.
If the model does not fit the data, we cannot rely on model parameters. Usually, they may be slightly off for a misspecified model (say in units), but with severe misspecification, they can be way off (sometimes even in tenths). The next step is then to look at the modification indices table. Collumn “mi” stands for the modification index. It represents the change in chi square statistics if you allow the given parameter. “~” stands for regression path (read as “predicted by”), “~~” denotes a correlation. “sepc.all” is the value of correlation or standardized regression path that the model missed.
Includes also a direct line from CS -> Reflection.
path.model1 <- 'PriBC ~ a*ZCommunalStrength
reflection ~ b*PriBC + c*TargetSharingSplit + f*CloseOthersTouchTest + d*SSTouchTest + e*OSTouchTest + g*ZCommunalStrength
stress ~ h*reflection
health ~ i*stress
TargetSharingSplit ~~ 0*ZCommunalStrength
SSTouchTest ~~ OSTouchTest
SSTouchTest ~~ CloseOthersTouchTest
OSTouchTest ~~ CloseOthersTouchTest
TargetSharingSplit ~~ SSTouchTest
TargetSharingSplit ~~ OSTouchTest
TargetSharingSplit ~~ CloseOthersTouchTest
'
fit.path.model1 <- sem(path.model1, data = exdat, se = "bootstrap", bootstrap = nboot, mimic = "Mplus", missing = "ML")
fitmeasures(fit.path.model1, c("chisq", "df", "pvalue", "cfi", "tli", "rmsea", "rmsea.ci.lower", "rmsea.ci.upper", "srmr_mplus", "pnfi", "bic"))
## chisq df pvalue cfi tli
## 35.495 21.000 0.025 0.969 0.946
## rmsea rmsea.ci.lower rmsea.ci.upper pnfi bic
## 0.040 0.014 0.062 0.542 9787.026
As you can see, the model fits is relatively good, it fits the data approximately.
modificationindices(fit.path.model1, alpha = .05, sort. = TRUE, maximum.number = 5)
## lhs op rhs mi epc sepc.lv sepc.all
## 64 PriBC ~ reflection 7.502 0.263 0.263 0.432
## 92 ZCommunalStrength ~ CloseOthersTouchTest 6.595 0.139 0.139 0.139
## 70 PriBC ~ OSTouchTest 6.144 0.076 0.076 0.119
## 53 stress ~~ CloseOthersTouchTest 5.120 0.062 0.062 0.084
## 77 stress ~ CloseOthersTouchTest 5.117 0.076 0.076 0.102
## sepc.nox
## 64 0.432
## 92 0.139
## 70 0.119
## 53 0.084
## 77 0.102
parameterEstimates(fit.path.model1, rsquare = TRUE, standardized = TRUE)[1:13,]
## lhs op rhs label est se z
## 1 PriBC ~ ZCommunalStrength a 0.066 0.037 1.784
## 2 reflection ~ PriBC b 0.179 0.077 2.319
## 3 reflection ~ TargetSharingSplit c 0.159 0.066 2.400
## 4 reflection ~ CloseOthersTouchTest f 0.057 0.058 0.986
## 5 reflection ~ SSTouchTest d 0.076 0.060 1.262
## 6 reflection ~ OSTouchTest e 0.208 0.061 3.401
## 7 reflection ~ ZCommunalStrength g 0.170 0.063 2.710
## 8 stress ~ reflection h -0.271 0.035 -7.662
## 9 health ~ stress i 0.547 0.068 7.992
## 10 ZCommunalStrength ~~ TargetSharingSplit 0.000 0.000 NA
## 11 SSTouchTest ~~ OSTouchTest 0.435 0.050 8.758
## 12 CloseOthersTouchTest ~~ SSTouchTest 0.537 0.053 10.138
## 13 CloseOthersTouchTest ~~ OSTouchTest 0.263 0.055 4.811
## pvalue ci.lower ci.upper std.lv std.all std.nox
## 1 0.074 -0.030 0.124 0.066 0.103 0.103
## 2 0.020 -0.019 0.326 0.179 0.109 0.109
## 3 0.016 0.022 0.272 0.159 0.125 0.125
## 4 0.324 -0.061 0.177 0.057 0.054 0.054
## 5 0.207 -0.032 0.191 0.076 0.072 0.072
## 6 0.001 0.094 0.334 0.208 0.197 0.197
## 7 0.007 0.057 0.337 0.170 0.161 0.161
## 8 0.000 -0.328 -0.198 -0.271 -0.385 -0.385
## 9 0.000 0.415 0.689 0.547 0.396 0.396
## 10 NA 0.000 0.000 0.000 0.000 0.000
## 11 0.000 0.333 0.535 0.435 0.436 0.436
## 12 0.000 0.444 0.646 0.537 0.538 0.538
## 13 0.000 0.148 0.383 0.263 0.263 0.263
lavCor(fit.path.model1)
## PriBC rflctn stress health ZCmmnS TrgtSS ClsOTT
## PriBC 1.000
## reflection 0.165 1.000
## stress -0.019 -0.387 1.000
## health -0.083 -0.230 0.397 1.000
## ZCommunalStrength 0.108 0.178 -0.071 -0.054 1.000
## TargetSharingSplit 0.043 0.158 -0.056 -0.016 0.000 1.000
## CloseOthersTouchTest 0.072 0.188 0.026 0.028 0.135 0.151 1.000
## SSTouchTest 0.116 0.223 -0.055 -0.065 0.096 0.101 0.538
## OSTouchTest 0.118 0.261 -0.155 -0.130 -0.011 0.070 0.263
## SSTchT OSTchT
## PriBC
## reflection
## stress
## health
## ZCommunalStrength
## TargetSharingSplit
## CloseOthersTouchTest
## SSTouchTest 1.000
## OSTouchTest 0.436 1.000
For approximate fit (based on the RMSEA distribution). Statistical power for the detection of a likely misspecified model (RMSEA > .08).
df <- fit.path.model1@test[[1]]$df
alpha <- .05
n <- nrow(exdat)
rmsea0 <- .05 # RMSEA given H0
rmseaa <- .08 # RMSEA given Ha
ncp0 <- (n-1)*df*rmsea0**2 ;
ncpa <-(n-1)*df*rmseaa**2 ;
if(rmsea0 < rmseaa) {
cval <- qchisq(1-alpha,df=df,ncp=ncp0)
pwr.rmsea <- 1 - pchisq(cval,df=df,ncp=ncpa)
} else {
cval <- qchisq(alpha,df=df,ncp=ncp0)
pwr.rmsea <- pchisq(cval,df=df,ncp=ncpa)
}
rm(ncp0, ncpa, cval)
print(round(pwr.rmsea,10))
## [1] 0.8157743
The power to detect mild model misspecifications is sufficient.
semPaths(fit.path.model1, layout = "tree2", rotation = 2, nDigits = 2, "Standardized", intercepts = FALSE, residuals = FALSE,
fade = FALSE, nCharNodes = 0, sizeMan = 9, edge.label.cex = .9, edge.label.position = .5, curvature = 2)
Touchscales seem to share most of their variance that is predictive of reflection. Here, OSTouch gets the highest path estimate because it has highest bivariate correlation with reflection. However, that isn’t something that could back up a substantive interpretation of that sort.
These are Bayes Factors based on model selection / information criteria approach as proposed by Wagenmakers, 2007. Each BF represents the relative evidence in the data favoring alternative hypothesis (parameter freely estimated) over the null (the given parameter fixed to 0). Bayes Factors using BIC approximation implicitly assume unit information prior which makes them rather conservative with regard to the alternative hypothesis.
f1 <- NULL
bf1 <- NULL
posterior1 <- NULL
for(i in letters[1:9]){
f1 <- sem(path.model1, data = exdat, mimic = "Mplus", missing = "ML")
bf1[i] <- 1/(exp((BIC(f1) - BIC(sem(path.model1, data = exdat, mimic = "Mplus", missing = "ML",
constraints = paste(i, '==', '0', sep = ""))))/2))
posterior1[i] <- bf1[i]/(1+bf1[i])
}
data.frame(BF10 = bf1, Posterior = round(posterior1, 3))
## BF10 Posterior
## a 3.148734e-01 0.239
## b 8.142104e-01 0.449
## c 1.866956e+00 0.651
## d 1.048879e-01 0.095
## e 9.492683e+01 0.990
## f 7.952776e-02 0.074
## g 4.820713e+00 0.828
## h 9.072473e+13 1.000
## i 5.810263e+14 1.000
path.model1a <- 'PriBC ~ a*ZCommunalStrength
reflection ~ b*PriBC + c*TargetSharingSplit + d*CloseOthersTouchTest + e*ZCommunalStrength
stress ~ f*reflection
health ~ g*stress
CloseOthersTouchTest ~~ h*TargetSharingSplit
TargetSharingSplit ~~ 0*ZCommunalStrength
'
fit.path.model1a <- sem(path.model1a, data = exdat, se = "bootstrap", bootstrap = nboot, mimic = "Mplus", missing = "ML")
fitmeasures(fit.path.model1a, c("chisq", "df", "pvalue", "cfi", "tli", "rmsea", "rmsea.ci.lower", "rmsea.ci.upper", "srmr_mplus", "pnfi", "bic"))
## chisq df pvalue cfi tli
## 21.626 13.000 0.061 0.957 0.930
## rmsea rmsea.ci.lower rmsea.ci.upper pnfi bic
## 0.039 0.000 0.067 0.558 7527.887
The model fits the data exactly.
#####Modification indices
#modificationindices(fit.path.model1a, alpha = .05, sort. = TRUE, maximum.number = 5)
parameterEstimates(fit.path.model1a, rsquare = TRUE, standardized = TRUE)[1:8,]
## lhs op rhs label est se z
## 1 PriBC ~ ZCommunalStrength a 0.065 0.039 1.678
## 2 reflection ~ PriBC b 0.222 0.080 2.781
## 3 reflection ~ TargetSharingSplit c 0.168 0.068 2.463
## 4 reflection ~ CloseOthersTouchTest d 0.151 0.048 3.127
## 5 reflection ~ ZCommunalStrength e 0.159 0.054 2.942
## 6 stress ~ reflection f -0.271 0.035 -7.726
## 7 health ~ stress g 0.547 0.064 8.577
## 8 TargetSharingSplit ~~ CloseOthersTouchTest h 0.125 0.043 2.886
## pvalue ci.lower ci.upper std.lv std.all std.nox
## 1 0.093 -0.022 0.134 0.065 0.102 0.102
## 2 0.005 0.060 0.384 0.222 0.135 0.135
## 3 0.014 0.037 0.302 0.168 0.131 0.131
## 4 0.002 0.057 0.240 0.151 0.143 0.143
## 5 0.003 0.075 0.292 0.159 0.150 0.150
## 6 0.000 -0.337 -0.196 -0.271 -0.386 -0.386
## 7 0.000 0.415 0.681 0.547 0.396 0.396
## 8 0.004 0.029 0.208 0.125 0.151 0.151
#####Bivariate correlations
#lavCor(fit.path.model1a)
For approximate fit (based on the RMSEA distribution). Statistical power for the detection of a likely misspecified model (RMSEA > .08).
df <- fit.path.model1a@test[[1]]$df
alpha <- .05
n <- nrow(exdat)
rmsea0 <- .05 # RMSEA given H0
rmseaa <- .08 # RMSEA given Ha
ncp0 <- (n-1)*df*rmsea0**2 ;
ncpa <-(n-1)*df*rmseaa**2 ;
if(rmsea0 < rmseaa) {
cval <- qchisq(1-alpha,df=df,ncp=ncp0)
pwr.rmsea <- 1 - pchisq(cval,df=df,ncp=ncpa)
} else {
cval <- qchisq(alpha,df=df,ncp=ncp0)
pwr.rmsea <- pchisq(cval,df=df,ncp=ncpa)
}
rm(ncp0, ncpa, cval)
print(round(pwr.rmsea,10))
## [1] 0.6443162
The power to detect mild model misspecifications is rather low for this and next two models.
semPaths(fit.path.model1a, layout = "tree2", rotation = 2, nDigits = 2, "Standardized", intercepts = FALSE, residuals = FALSE,
fade = FALSE, nCharNodes = 0, sizeMan = 9, edge.label.cex = .9, edge.label.position = .5)
These are Bayes Factors based on model selection / information criteria approach as proposed by Wagenmakers, 2007. Each BF represents the relative evidence in the data favoring alternative hypothesis (parameter freely estimated) over the null (the given parameter fixed to 0). Bayes Factors using BIC approximation implicitly assume unit information prior which makes them rather conservative with regard to the alternative hypothesis.
f1a <- NULL
bf1a <- NULL
posterior1a <- NULL
for(i in letters[1:8]){
f1a <- sem(path.model1a, data = exdat, mimic = "Mplus", missing = "ML")
bf1a[i] <- 1/(exp((BIC(f1a) - BIC(sem(path.model1a, data = exdat, mimic = "Mplus", missing = "ML",
constraints = paste(i, '==', '0', sep = ""))))/2))
posterior1a[i] <- bf1a[i]/(1+bf1a[i])
}
data.frame(BF10 = bf1a, Posterior = round(posterior1a, 3))
## BF10 Posterior
## a 2.980744e-01 0.230
## b 3.121931e+00 0.757
## c 2.285883e+00 0.696
## d 4.538370e+00 0.819
## e 2.185709e+00 0.686
## f 9.072473e+13 1.000
## g 5.810263e+14 1.000
## h 6.931197e+00 0.874
path.model1b <- 'PriBC ~ a*ZCommunalStrength
reflection ~ b*PriBC + c*TargetSharingSplit + d*SSTouchTest + e*ZCommunalStrength
stress ~ f*reflection
health ~ g*stress
SSTouchTest ~~ h*TargetSharingSplit
TargetSharingSplit ~~ 0*ZCommunalStrength
'
fit.path.model1b <- sem(path.model1b, data = exdat, se = "bootstrap", bootstrap = nboot, mimic = "Mplus", missing = "ML")
fitmeasures(fit.path.model1b, c("chisq", "df", "pvalue", "cfi", "tli", "rmsea", "rmsea.ci.lower", "rmsea.ci.upper", "srmr_mplus", "pnfi", "bic"))
## chisq df pvalue cfi tli
## 16.586 13.000 0.219 0.982 0.970
## rmsea rmsea.ci.lower rmsea.ci.upper pnfi bic
## 0.025 0.000 0.057 0.572 7526.982
The model fits the data exactly.
#####Modification indices
#modificationindices(fit.path.model1b, alpha = .05, sort. = TRUE, maximum.number = 5)
parameterEstimates(fit.path.model1b, rsquare = TRUE, standardized = TRUE)[1:8,]
## lhs op rhs label est se z
## 1 PriBC ~ ZCommunalStrength a 0.065 0.037 1.791
## 2 reflection ~ PriBC b 0.203 0.069 2.928
## 3 reflection ~ TargetSharingSplit c 0.172 0.071 2.416
## 4 reflection ~ SSTouchTest d 0.195 0.054 3.598
## 5 reflection ~ ZCommunalStrength e 0.162 0.053 3.052
## 6 stress ~ reflection f -0.271 0.034 -8.033
## 7 health ~ stress g 0.547 0.059 9.196
## 8 TargetSharingSplit ~~ SSTouchTest h 0.083 0.038 2.194
## pvalue ci.lower ci.upper std.lv std.all std.nox
## 1 0.073 -0.010 0.140 0.065 0.102 0.102
## 2 0.003 0.035 0.328 0.203 0.123 0.123
## 3 0.016 0.020 0.292 0.172 0.135 0.135
## 4 0.000 0.075 0.296 0.195 0.184 0.184
## 5 0.002 0.060 0.265 0.162 0.153 0.153
## 6 0.000 -0.329 -0.195 -0.271 -0.385 -0.385
## 7 0.000 0.428 0.656 0.547 0.396 0.396
## 8 0.028 0.019 0.154 0.083 0.101 0.101
#####Bivariate correlations
#lavCor(fit.path.model1b)
semPaths(fit.path.model1b, layout = "tree2", rotation = 2, nDigits = 2, "Standardized", intercepts = FALSE, residuals = FALSE,
fade = FALSE, nCharNodes = 0, sizeMan = 9, edge.label.cex = .9, edge.label.position = .5)
These are Bayes Factors based on model selection / information criteria approach as proposed by Wagenmakers, 2007. Each BF represents the relative evidence in the data favoring alternative hypothesis (parameter freely estimated) over the null (the given parameter fixed to 0). Bayes Factors using BIC approximation implicitly assume unit information prior which makes them rather conservative with regard to the alternative hypothesis.
f1b <- NULL
bf1b <- NULL
posterior1b <- NULL
for(i in letters[1:8]){
f1b <- sem(path.model1b, data = exdat, mimic = "Mplus", missing = "ML")
bf1b[i] <- 1/(exp((BIC(f1b) - BIC(sem(path.model1b, data = exdat, mimic = "Mplus", missing = "ML",
constraints = paste(i, '==', '0', sep = ""))))/2))
posterior1b[i] <- bf1b[i]/(1+bf1b[i])
}
data.frame(BF10 = bf1b, Posterior = round(posterior1b, 3))
## BF10 Posterior
## a 2.993474e-01 0.230
## b 1.627116e+00 0.619
## c 3.100855e+00 0.756
## d 1.118658e+02 0.991
## e 2.818561e+00 0.738
## f 9.072473e+13 1.000
## g 5.810263e+14 1.000
## h 4.419832e-01 0.307
path.model1c <- 'PriBC ~ a*ZCommunalStrength
reflection ~ b*PriBC + c*TargetSharingSplit + d*OSTouchTest + e*ZCommunalStrength
stress ~ f*reflection
health ~ g*stress
OSTouchTest ~~ h*TargetSharingSplit
TargetSharingSplit ~~ 0*ZCommunalStrength
'
fit.path.model1c <- sem(path.model1c, data = exdat, se = "bootstrap", bootstrap = nboot, mimic = "Mplus", missing = "ML")
fitmeasures(fit.path.model1c, c("chisq", "df", "pvalue", "cfi", "tli", "rmsea", "rmsea.ci.lower", "rmsea.ci.upper", "srmr_mplus", "pnfi", "bic"))
## chisq df pvalue cfi tli
## 16.905 13.000 0.204 0.981 0.969
## rmsea rmsea.ci.lower rmsea.ci.upper pnfi bic
## 0.026 0.000 0.058 0.573 7517.666
The model fits the data exactly.
#####Modification indices
#modificationindices(fit.path.model1c, alpha = .05, sort. = TRUE, maximum.number = 5)
#parameterEstimates(fit.path.model1c, rsquare = TRUE, standardized = TRUE)[1:8,]
#####Bivariate correlations
#lavCor(fit.path.model1c)
semPaths(fit.path.model1c, layout = "tree2", rotation = 2, nDigits = 2, "Standardized", intercepts = FALSE, residuals = FALSE,
fade = FALSE, nCharNodes = 0, sizeMan = 9, edge.label.cex = .9, edge.label.position = .5)
These are Bayes Factors based on model selection / information criteria approach as proposed by Wagenmakers, 2007. Each BF represents the relative evidence in the data favoring alternative hypothesis (parameter freely estimated) over the null (the given parameter fixed to 0). Bayes Factors using BIC approximation implicitly assume unit information prior which makes them rather conservative with regard to the alternative hypothesis.
f1c <- NULL
bf1c <- NULL
posterior1c <- NULL
for(i in letters[1:8]){
f1c <- sem(path.model1c, data = exdat, mimic = "Mplus", missing = "ML")
bf1c[i] <- 1/(exp((BIC(f1c) - BIC(sem(path.model1c, data = exdat, mimic = "Mplus", missing = "ML",
constraints = paste(i, '==', '0', sep = ""))))/2))
posterior1c[i] <- bf1c[i]/(1+bf1c[i])
}
data.frame(BF10 = bf1c, Posterior = round(posterior1c, 3))
## BF10 Posterior
## a 3.185981e-01 0.242
## b 1.028741e+00 0.507
## c 3.932608e+00 0.797
## d 3.770004e+04 1.000
## e 1.218759e+01 0.924
## f 9.072473e+13 1.000
## g 5.810263e+14 1.000
## h 1.382756e-01 0.121
anova(fit.path.model1c, fit.path.model1b, fit.path.model1a)
## Chi Square Difference Test
##
## Df AIC BIC Chisq Chisq diff Df diff Pr(>Chisq)
## fit.path.model1c 13 7428.1 7517.7 16.905
## fit.path.model1b 13 7437.4 7527.0 16.586 -0.3190 0 1
## fit.path.model1a 13 7438.3 7527.9 21.626 5.0402 0 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Comparison of models in terms of fit based on likelihood ratio test. Models involving SST and OST do not differ from each other but they both fit the data better than the model with COT. It may mean that in the context of modelled variables, COT involves a bit more (but still not a significant portion) of extraneous variance, not explained by the model. Specifically, COT correlates with CS (.14) and that correlation is not accounted for in the model (although the correlation is not so substantial as to cause significantly bad global fit). SST and OST are in no relationship to CS and that’s why they fare a bit better (modelled zero correlation is also observed in the data - statistical zero).
Also involving a direct path from CS to reflection. OK?
path.model2 <- 'PriBC ~ a*ZCommunalStrength
reflection ~ b*PriBC + c*TargetSharingSplit + d*CloseOthersTouchTest + e*ZCommunalStrength
rumination ~ f*ZCommunalStrength + g*CloseOthersTouchTest + h*int_COT_CS
stress ~ i*reflection + j*rumination
health ~ k*stress
reflection ~~ l*rumination
TargetSharingSplit ~~ m*CloseOthersTouchTest
TargetSharingSplit ~~ 0*ZCommunalStrength
CloseOthersTouchTest ~~ ZCommunalStrength
CloseOthersTouchTest ~~ int_COT_CS
int_COT_CS ~~ ZCommunalStrength
'
fit.path.model2 <- sem(path.model2, data = exdat, se = "bootstrap", bootstrap = nboot, mimic = "Mplus", missing = "ML")
fitmeasures(fit.path.model2, c("chisq", "df", "pvalue", "cfi", "tli", "rmsea", "rmsea.ci.lower", "rmsea.ci.upper", "srmr_mplus", "pnfi", "bic"))
## chisq df pvalue cfi tli
## 18.130 20.000 0.579 1.000 1.008
## rmsea rmsea.ci.lower rmsea.ci.upper pnfi bic
## 0.000 0.000 0.037 0.535 9691.396
The model fits the data exactly.
#####Modification indices
#modificationindices(fit.path.model2, alpha = .05, sort. = TRUE, maximum.number = 5)
parameterEstimates(fit.path.model2, rsquare = TRUE)[1:13,]
## lhs op rhs label est se z
## 1 PriBC ~ ZCommunalStrength a 0.069 0.033 2.084
## 2 reflection ~ PriBC b 0.214 0.077 2.778
## 3 reflection ~ TargetSharingSplit c 0.129 0.043 2.986
## 4 reflection ~ CloseOthersTouchTest d 0.151 0.051 2.978
## 5 reflection ~ ZCommunalStrength e 0.161 0.055 2.913
## 6 rumination ~ ZCommunalStrength f -0.173 0.077 -2.238
## 7 rumination ~ CloseOthersTouchTest g 0.014 0.072 0.193
## 8 rumination ~ int_COT_CS h -0.196 0.078 -2.507
## 9 stress ~ reflection i -0.094 0.032 -2.949
## 10 stress ~ rumination j 0.280 0.028 10.045
## 11 health ~ stress k 0.547 0.062 8.814
## 12 reflection ~~ rumination l -0.658 0.072 -9.128
## 13 TargetSharingSplit ~~ CloseOthersTouchTest m 0.122 0.036 3.392
## pvalue ci.lower ci.upper
## 1 0.037 0.018 0.152
## 2 0.005 0.042 0.386
## 3 0.003 0.041 0.223
## 4 0.003 0.053 0.282
## 5 0.004 0.051 0.269
## 6 0.025 -0.337 -0.009
## 7 0.847 -0.122 0.169
## 8 0.012 -0.323 -0.017
## 9 0.003 -0.165 -0.027
## 10 0.000 0.226 0.335
## 11 0.000 0.427 0.675
## 12 0.000 -0.829 -0.485
## 13 0.001 0.049 0.194
#####Bivariate correlations
#lavCor(fit.path.model2)
For approximate fit (based on the RMSEA distribution). Statistical power for the detection of a likely misspecified model (RMSEA > .08). Models 1SST and 1OST have the same power.
df <- fit.path.model2@test[[1]]$df
alpha <- .05
n <- nrow(exdat)
rmsea0 <- .05 # RMSEA given H0
rmseaa <- .08 # RMSEA given Ha
ncp0 <- (n-1)*df*rmsea0**2 ;
ncpa <-(n-1)*df*rmseaa**2 ;
if(rmsea0 < rmseaa) {
cval <- qchisq(1-alpha,df=df,ncp=ncp0)
pwr.rmsea <- 1 - pchisq(cval,df=df,ncp=ncpa)
} else {
cval <- qchisq(alpha,df=df,ncp=ncp0)
pwr.rmsea <- pchisq(cval,df=df,ncp=ncpa)
}
rm(ncp0, ncpa, cval)
print(round(pwr.rmsea,10))
## [1] 0.7994089
The power is sufficient. ####Path model
semPaths(fit.path.model2, layout = "tree2", rotation = 2, nDigits = 2, "Standardized", intercepts = FALSE, residuals = FALSE,
fade = FALSE, nCharNodes = 0, sizeMan = 9, edge.label.cex = .9, edge.label.position = .45, curvature = 3)
These are Bayes Factors based on model selection / information criteria approach as proposed by Wagenmakers, 2007. Each BF represents the relative evidence in the data favoring alternative hypothesis (parameter freely estimated) over the null (the given parameter fixed to 0). Bayes Factors using BIC approximation implicitly assume unit information prior which makes them rather conservative with regard to the alternative hypothesis.
f2 <- NULL
bf2 <- NULL
posterior2 <- NULL
for(i in letters[1:13]){
f2 <- sem(path.model2, data = exdat, mimic = "Mplus", missing = "ML")
bf2[i] <- 1/(exp((BIC(f2) - BIC(sem(path.model2, data = exdat, mimic = "Mplus", missing = "ML",
constraints = paste(i, '==', '0', sep = ""))))/2))
posterior2[i] <- bf2[i]/(1+bf2[i])
}
data.frame(BF10 = bf2, Posterior = round(posterior2, 3))
## BF10 Posterior
## a 3.673561e-01 0.269
## b 8.460169e+00 0.894
## c 1.047416e+00 0.512
## d 4.507381e+00 0.818
## e 2.448003e+00 0.710
## f 8.157399e-01 0.449
## g 4.920057e-02 0.047
## h 2.373109e+00 0.704
## i 3.459359e+00 0.776
## j 1.685678e+21 1.000
## k 5.810263e+14 1.000
## l 1.008702e+26 1.000
## m 5.679214e+00 0.850
Also involving a direct path from CS to reflection. OK?
path.model2b <- 'PriBC ~ a*ZCommunalStrength
reflection ~ b*PriBC + c*TargetSharingSplit + d*SSTouchTest + e*ZCommunalStrength
rumination ~ f*ZCommunalStrength + g*SSTouchTest + h*int_SST_CS
stress ~ i*reflection + j*rumination
health ~ k*stress
reflection ~~ l*rumination
TargetSharingSplit ~~ m*SSTouchTest
TargetSharingSplit ~~ 0*ZCommunalStrength
SSTouchTest ~~ ZCommunalStrength
SSTouchTest ~~ int_SST_CS
int_SST_CS ~~ ZCommunalStrength
'
fit.path.model2b <- sem(path.model2b, data = exdat, se = "bootstrap", bootstrap = nboot, mimic = "Mplus", missing = "ML")
fitmeasures(fit.path.model2b, c("chisq", "df", "pvalue", "cfi", "tli", "rmsea", "rmsea.ci.lower", "rmsea.ci.upper", "srmr_mplus", "pnfi", "bic"))
## chisq df pvalue cfi tli
## 15.584 20.000 0.742 1.000 1.019
## rmsea rmsea.ci.lower rmsea.ci.upper pnfi bic
## 0.000 0.000 0.030 0.537 9740.340
The model fits the data exactly (in statistical sense, within the bounds of alpha, of course) - the path estimates are thus fully interpretable.
#####Modification indices
#modificationindices(fit.path.model2b, alpha = .05, sort. = TRUE, maximum.number = 5)
parameterEstimates(fit.path.model2b, rsquare = TRUE)[1:13,]
## lhs op rhs label est se z
## 1 PriBC ~ ZCommunalStrength a 0.069 0.036 1.923
## 2 reflection ~ PriBC b 0.195 0.084 2.313
## 3 reflection ~ TargetSharingSplit c 0.139 0.054 2.584
## 4 reflection ~ SSTouchTest d 0.194 0.051 3.839
## 5 reflection ~ ZCommunalStrength e 0.163 0.055 2.989
## 6 rumination ~ ZCommunalStrength f -0.150 0.086 -1.747
## 7 rumination ~ SSTouchTest g -0.087 0.069 -1.255
## 8 rumination ~ int_SST_CS h -0.093 0.080 -1.170
## 9 stress ~ reflection i -0.094 0.031 -2.990
## 10 stress ~ rumination j 0.280 0.022 12.802
## 11 health ~ stress k 0.547 0.072 7.617
## 12 reflection ~~ rumination l -0.653 0.083 -7.902
## 13 TargetSharingSplit ~~ SSTouchTest m 0.083 0.041 2.022
## pvalue ci.lower ci.upper
## 1 0.054 -0.010 0.136
## 2 0.021 0.014 0.393
## 3 0.010 0.042 0.258
## 4 0.000 0.082 0.292
## 5 0.003 0.086 0.306
## 6 0.081 -0.332 0.014
## 7 0.210 -0.215 0.072
## 8 0.242 -0.246 0.079
## 9 0.003 -0.160 -0.026
## 10 0.000 0.228 0.316
## 11 0.000 0.396 0.699
## 12 0.000 -0.808 -0.467
## 13 0.043 -0.002 0.166
#####Bivariate correlations
#lavCor(fit.path.model2b)
semPaths(fit.path.model2b, layout = "tree2", rotation = 2, nDigits = 2, "Standardized", intercepts = FALSE, residuals = FALSE,
fade = FALSE, nCharNodes = 0, sizeMan = 9, edge.label.cex = .9, edge.label.position = .45, curvature = 3)
These are Bayes Factors based on model selection / information criteria approach as proposed by Wagenmakers, 2007. Each BF represents the relative evidence in the data favoring alternative hypothesis (parameter freely estimated) over the null (the given parameter fixed to 0). Bayes Factors using BIC approximation implicitly assume unit information prior which makes them rather conservative with regard to the alternative hypothesis.
f2b <- NULL
bf2b <- NULL
posterior2b <- NULL
for(i in letters[1:13]){
f2b <- sem(path.model2b, data = exdat, mimic = "Mplus", missing = "ML")
bf2b[i] <- 1/(exp((BIC(f2b) - BIC(sem(path.model2b, data = exdat, mimic = "Mplus", missing = "ML",
constraints = paste(i, '==', '0', sep = ""))))/2))
posterior2b[i] <- bf2b[i]/(1+bf2b[i])
}
data.frame(BF10 = bf2b, Posterior = round(posterior2b, 3))
## BF10 Posterior
## a 3.567341e-01 0.263
## b 3.644417e+00 0.785
## c 1.872462e+00 0.652
## d 1.047007e+02 0.991
## e 2.997525e+00 0.750
## f 4.060272e-01 0.289
## g 1.234676e-01 0.110
## h 1.272959e-01 0.113
## i 3.459359e+00 0.776
## j 1.685678e+21 1.000
## k 5.810263e+14 1.000
## l 4.761972e+25 1.000
## m 4.208289e-01 0.296
Also involving a direct path from CS to reflection. OK?
path.model2c <- 'PriBC ~ a*ZCommunalStrength
reflection ~ b*PriBC + c*TargetSharingSplit + d*OSTouchTest + e*ZCommunalStrength
rumination ~ f*ZCommunalStrength + g*OSTouchTest + h*int_OST_CS
stress ~ i*reflection + j*rumination
health ~ k*stress
reflection ~~ l*rumination
TargetSharingSplit ~~ m*OSTouchTest
TargetSharingSplit ~~ 0*ZCommunalStrength
OSTouchTest ~~ ZCommunalStrength
OSTouchTest ~~ int_OST_CS
int_OST_CS ~~ ZCommunalStrength
'
fit.path.model2c <- sem(path.model2c, data = exdat, se = "bootstrap", bootstrap = nboot, mimic = "Mplus", missing = "ML")
fitmeasures(fit.path.model2c, c("chisq", "df", "pvalue", "cfi", "tli", "rmsea", "rmsea.ci.lower", "rmsea.ci.upper", "srmr_mplus", "pnfi", "bic"))
## chisq df pvalue cfi tli
## 27.806 20.000 0.114 0.982 0.968
## rmsea rmsea.ci.lower rmsea.ci.upper pnfi bic
## 0.030 0.000 0.055 0.523 9735.083
The model fits the data exactly (in statistical sense, within the bounds of alpha, of course) - the path estimates are thus fully interpretable.
#####Modification indices
#modificationindices(fit.path.model2c, alpha = .05, sort. = TRUE, maximum.number = 5)
parameterEstimates(fit.path.model2c, rsquare = TRUE)[1:13,]
## lhs op rhs label est se z
## 1 PriBC ~ ZCommunalStrength a 0.068 0.036 1.879
## 2 reflection ~ PriBC b 0.185 0.088 2.101
## 3 reflection ~ TargetSharingSplit c 0.142 0.054 2.603
## 4 reflection ~ OSTouchTest d 0.257 0.053 4.862
## 5 reflection ~ ZCommunalStrength e 0.185 0.057 3.254
## 6 rumination ~ ZCommunalStrength f -0.157 0.088 -1.791
## 7 rumination ~ OSTouchTest g -0.129 0.070 -1.848
## 8 rumination ~ int_OST_CS h -0.006 0.096 -0.062
## 9 stress ~ reflection i -0.094 0.030 -3.143
## 10 stress ~ rumination j 0.280 0.024 11.448
## 11 health ~ stress k 0.547 0.059 9.306
## 12 reflection ~~ rumination l -0.637 0.065 -9.784
## 13 TargetSharingSplit ~~ OSTouchTest m 0.058 0.041 1.414
## pvalue ci.lower ci.upper
## 1 0.060 -0.009 0.146
## 2 0.036 -0.014 0.360
## 3 0.009 0.015 0.242
## 4 0.000 0.164 0.365
## 5 0.001 0.077 0.301
## 6 0.073 -0.349 0.015
## 7 0.065 -0.281 0.009
## 8 0.951 -0.196 0.188
## 9 0.002 -0.160 -0.038
## 10 0.000 0.229 0.325
## 11 0.000 0.456 0.675
## 12 0.000 -0.779 -0.509
## 13 0.157 -0.025 0.150
#####Bivariate correlations
#lavCor(fit.path.model2c)
semPaths(fit.path.model2c, layout = "tree2", rotation = 2, nDigits = 2, "Standardized", intercepts = FALSE, residuals = FALSE,
fade = FALSE, nCharNodes = 0, sizeMan = 9, edge.label.cex = .9, edge.label.position = .45, curvature = 3)
These are Bayes Factors based on model selection / information criteria approach as proposed by Wagenmakers, 2007. Each BF represents the relative evidence in the data favoring alternative hypothesis (parameter freely estimated) over the null (the given parameter fixed to 0). Bayes Factors using BIC approximation implicitly assume unit information prior which makes them rather conservative with regard to the alternative hypothesis.
f2c <- NULL
bf2c <- NULL
posterior2c <- NULL
for(i in letters[1:13]){
f2c <- sem(path.model2c, data = exdat, mimic = "Mplus", missing = "ML")
bf2c[i] <- 1/(exp((BIC(f2c) - BIC(sem(path.model2c, data = exdat, mimic = "Mplus", missing = "ML",
constraints = paste(i, '==', '0', sep = ""))))/2))
posterior2c[i] <- bf2c[i]/(1+bf2c[i])
}
data.frame(BF10 = bf2c, Posterior = round(posterior2c, 3))
## BF10 Posterior
## a 3.489356e-01 0.259
## b 2.479296e+00 0.713
## c 2.359068e+00 0.702
## d 4.928325e+04 1.000
## e 1.176502e+01 0.922
## f 5.142526e-01 0.340
## g 3.960512e-01 0.284
## h 4.824207e-02 0.046
## i 3.459359e+00 0.776
## j 1.685678e+21 1.000
## k 5.810263e+14 1.000
## l 8.773228e+24 1.000
## m 1.385690e-01 0.122
anova(fit.path.model2, fit.path.model2b, fit.path.model2c)
## Chi Square Difference Test
##
## Df AIC BIC Chisq Chisq diff Df diff Pr(>Chisq)
## fit.path.model2 20 9553.0 9691.4 18.130
## fit.path.model2b 20 9601.9 9740.3 15.584 -2.5453 0 1
## fit.path.model2c 20 9596.7 9735.1 27.806 12.2212 0 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Comparison of models in terms of fit based on likelihood ratio test. Model involving OST fits the data significantly worse than models with COT and SST (they don’t differ from each other in terms of fit).