Skip to content

Commit dff0f98

Browse files
committed
more estimators for cfa, change standardization output
1 parent 2aac174 commit dff0f98

6 files changed

+255
-167
lines changed

DESCRIPTION

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Package: jaspFactor
22
Type: Package
33
Title: Factor Module for JASP
44
Version: 0.19.0
5-
Date: 2023-04-14
5+
Date: 2024-08-19
66
Author: JASP Team
77
Website: jasp-stats.org
88
Maintainer: JASP Team <[email protected]>

R/confirmatoryfactoranalysis.R

+129-82
Large diffs are not rendered by default.

inst/help/ConfirmatoryFactorAnalysis.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ JASP allows the factors in turn to be indicators of a second-order factor. This
6060
### Advanced
6161
-------
6262
- Emulation: Emulate results from different software
63-
- Error calculation: Change how standard errors for the parameters are computed
63+
- Error calculation: Change how standard errors for the parameters are computed, if bootstrap the CIs are percentile bootstrap type
6464
- Estimator: change the estimator for the CFA (Auto: ML if only scale variables used, WLS otherwise)
6565
- Standardization: display standardized parameters for different standardization schemes
6666
- Missing data handling: change the missing data handling method.

inst/help/forQml/tooltipEstimators.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
### Help on Estimators
3+
Some of the estimators come with options that are set in the background:
4+
5+
- Estimators without extra effects (standard errors and model test are standard):
6+
- ML, GLS, WLS, ULS, DWLS, DLS
7+
8+
- Extensions of ML-estimators with extra effects:
9+
- MLM: classic robust se (se="robust.sem"), Satorra-Bentler test statistic (test="satorra.bentler")
10+
- MLMV: classic robust se, scaled and shifted test statistic (test="scaled.shifted")
11+
- MLMVS: classic robust se, mean and var adjusted Satterthwaite style test statistic (test="mean.var.adjusted")
12+
- MLF: first-order standard se (information="first.order"), standard test
13+
- MLR: Huber-White robust se (se="robust.huber.white"), Yuan-Bentler T2-star test statistic (test="yuan.bentler.mplus")
14+
15+
- Others:
16+
- WLSM: implies DWLS with scaled test and robust se
17+
- WLSMV: implies DWLS with mean and var adjusted test and robust se
18+
- ULSM: implies ULS with scaled test and robust se
19+
- ULSMV: implies ULS with mean-var adjusted test and robust se
20+
21+
- Note: If you specify "Standard errors" instead of leaving it at default the corresponding options set by the estimators in the background will be overwritten

inst/qml/ConfirmatoryFactorAnalysis.qml

+68-44
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ Form
102102
label: qsTr("Model identification")
103103
name: "modelIdentification"
104104
values: [
105-
{ label: qsTr("Factor variances"), value: "factorVariance" },
106105
{ label: qsTr("Marker variable"), value: "markerVariable" },
106+
{ label: qsTr("Factor variances"), value: "factorVariance" },
107107
{ label: qsTr("Effects coding"), value: "effectsCoding" }
108108
]
109109
}
@@ -206,64 +206,88 @@ Form
206206
Section
207207
{
208208
title: qsTr("Advanced")
209-
RadioButtonGroup
210-
{
211-
title: qsTr("Mimic package")
212-
name: "packageMimiced"
213-
RadioButton { label: qsTr("Lavaan"); value: "lavaan" ; checked: true }
214-
RadioButton { label: qsTr("Mplus") ; value: "Mplus" }
215-
RadioButton { label: qsTr("EQS") ; value: "EQS" }
216-
}
217209

218-
Group
219-
{
220-
title: qsTr("Error calculation")
221-
CIField { text: qsTr("CI level"); name: "ciLevel" }
222-
RadioButtonGroup
210+
Group {
211+
DropDown
223212
{
224-
title: qsTr("Standard error")
225-
name: "seType"
226-
RadioButton { label: qsTr("Standard"); value: "standard"; checked: true}
227-
RadioButton { label: qsTr("Robust"); value: "robust" }
228-
RadioButton {
229-
label: qsTr("Bootstrap")
230-
value: "bootstrap"
231-
IntegerField {
232-
label: qsTr("Bootstrap samples")
233-
name: "bootstrapSamples"
234-
defaultValue: 1000
235-
min: 100
236-
max: 1000000
237-
}
213+
name: "packageMimiced"
214+
label: qsTr("Mimic")
215+
values: [
216+
{ label: qsTr("Lavaan"), value: "lavaan" },
217+
{ label: qsTr("Mplus"), value: "mplus" },
218+
{ label: qsTr("EQS"), value: "eqs" }
219+
]
220+
}
221+
RowLayout
222+
{
223+
DropDown
224+
{
225+
name: "estimator"
226+
label: qsTr("Estimator")
227+
id: estimator
228+
values: [
229+
{ label: qsTr("Default"), value: "default" },
230+
{ label: qsTr("ML"), value: "ml" },
231+
{ label: qsTr("GLS"), value: "gls" },
232+
{ label: qsTr("WLS"), value: "wls" },
233+
{ label: qsTr("ULS"), value: "uls" },
234+
{ label: qsTr("DWLS"), value: "dwls" },
235+
{ label: qsTr("DLS"), value: "dls" },
236+
{ label: qsTr("PML"), value: "pml" },
237+
{ label: qsTr("MLM"), value: "mlm" },
238+
{ label: qsTr("MLMV"), value: "mlmv" },
239+
{ label: qsTr("MLMVS"), value: "mlmvs" },
240+
{ label: qsTr("MLF"), value: "mlf" },
241+
{ label: qsTr("MLR"), value: "mlr" },
242+
{ label: qsTr("WLSM"), value: "wlsm" },
243+
{ label: qsTr("WLSMV"), value: "wlsmv" },
244+
{ label: qsTr("ULSM"), value: "ulsm" },
245+
{ label: qsTr("ULSMV"), value: "ulsmv" }
246+
]
247+
}
248+
HelpButton
249+
{
250+
toolTip: qsTr("Click for more information")
251+
helpPage: "forQml/tooltipEstimators"
238252
}
239253
}
240-
}
241-
242-
RadioButtonGroup
243-
{
244-
title: qsTr("Estimator")
245-
name: "estimator"
246-
RadioButton { label: qsTr("Auto") ; value: "default"; checked: true }
247-
RadioButton { label: qsTr("ML") ; value: "maximumLikelihood" }
248-
RadioButton { label: qsTr("GLS") ; value: "generalizedLeastSquares" }
249-
RadioButton { label: qsTr("WLS") ; value: "weightedLeastSquares" }
250-
RadioButton { label: qsTr("ULS") ; value: "unweightedLeastSquares" }
251-
RadioButton { label: qsTr("DWLS") ; value: "diagonallyWeightedLeastSquares" }
252-
}
253-
254-
DropDown
254+
DropDown
255+
{
256+
label: qsTr("Standard errors")
257+
name: "seType"
258+
id: errorCalc
259+
values: [
260+
{ label: qsTr("Default"), value: "default" },
261+
{ label: qsTr("Standard"), value: "standard" },
262+
{ label: qsTr("Robust"), value: "robust" },
263+
{ label: qsTr("Bootstrap"), value: "bootstrap" }
264+
]
265+
}
266+
IntegerField
267+
{
268+
visible: errorCalc.value == "bootstrap"
269+
name: "bootstrapSamples"
270+
label: qsTr(" Bootstrap samples")
271+
defaultValue: 1000
272+
min: 100
273+
max: 1000000
274+
}
275+
CIField { text: qsTr(" CI level"); name: "ciLevel" }
276+
277+
DropDown
255278
{
256279
name: "naAction"
257280
label: qsTr("Missing data handling")
258281
values:
259282
[
260-
{ label: qsTr("FIML") , value: "fiml" },
261283
{ label: qsTr("Listwise deletion") , value: "listwise" },
284+
{ label: qsTr("FIML") , value: "fiml" },
262285
{ label: qsTr("Pairwise") , value: "pairwise" },
263286
{ label: qsTr("Two-stage") , value: "twoStage" },
264287
{ label: qsTr("Robust two-stage") , value: "twoStageRobust" },
265288
]
266289
}
290+
}
267291

268292
RadioButtonGroup
269293
{

tests/testthat/test-confirmatoryfactoranalysis.R

+35-39
Original file line numberDiff line numberDiff line change
@@ -201,48 +201,44 @@ test_that("[CFA Second order] Chi-square test table results match", {
201201
})
202202

203203

204-
test_that("Bootstrapping works", {
205-
options <- jaspTools::analysisOptions("confirmatoryFactorAnalysis")
206-
options$group <- ""
207-
options$invarianceTesting <- "configural"
208-
options$packageMimiced <- "lavaan"
209-
options$seType <- "bootstrap"
210-
options$bootstrapSamples <- 100
211-
options$estimator <- "default"
212-
options$standardized <- "none"
213-
options$factors <- list(
214-
list(indicators = list("x1", "x2", "x3"), name = "Factor1", title = "Factor 1", types = rep("scale", 3)),
215-
list(indicators = list("x4", "x5", "x6"), name = "Factor2", title = "Factor 2", types = rep("scale", 3)),
216-
list(indicators = list("x7", "x8", "x9"), name = "Factor3", title = "Factor 3", types = rep("scale", 3))
217-
)
218-
options$modelIdentification <- "factorVariance"
219-
options$naAction <- "listwise"
220-
set.seed(1)
221-
results <- jaspTools::runAnalysis("confirmatoryFactorAnalysis", "holzingerswineford.csv", options)
204+
# factor loadings with bootstrapping are correct
205+
options <- jaspTools::analysisOptions("confirmatoryFactorAnalysis")
206+
options$group <- ""
207+
options$invarianceTesting <- "configural"
208+
options$packageMimiced <- "lavaan"
209+
options$seType <- "bootstrap"
210+
options$bootstrapSamples <- 100
211+
options$estimator <- "default"
212+
options$standardized <- "none"
213+
options$factors <- list(
214+
list(indicators = list("x1", "x2", "x3"), name = "Factor1", title = "Factor 1", types = rep("scale", 3)),
215+
list(indicators = list("x4", "x5", "x6"), name = "Factor2", title = "Factor 2", types = rep("scale", 3)),
216+
list(indicators = list("x7", "x8", "x9"), name = "Factor3", title = "Factor 3", types = rep("scale", 3))
217+
)
218+
options$modelIdentification <- "factorVariance"
219+
options$naAction <- "listwise"
220+
set.seed(1)
221+
results <- jaspTools::runAnalysis("confirmatoryFactorAnalysis", "holzingerswineford.csv", options)
222222

223+
test_that("Factor loadings table results match", {
223224
table <- results[["results"]][["estimates"]][["collection"]][["estimates_fl1"]][["data"]]
224225
jaspTools::expect_equal_tables(table,
225-
list(0.712022271311838, 1.11279383173753, 0.899620313867488,
226-
"Factor 1", 0, "x1", 0.0808465333987386, 11.1275063512065, 0.339182433474584,
227-
0.693156723678194, 0.49794051110941, "Factor 1",
228-
1.28623778294923e-10, "x2", 0.0774547818506273, 6.42878979466621,
229-
0.539990088382033, 0.805660643384033, 0.656156092628451,
230-
"Factor 1", 0, "x3", 0.0744212256974568, 8.81678696472846, 0.856032790026098,
231-
1.08543684864592, 0.989693449094392, "Factor 2",
232-
0, "x4", 0.0566367179185465, 17.4744138690689, 0.954112872546464,
233-
1.24054019999221, 1.10160465003145, "Factor 2",
234-
0, "x5", 0.0626757561168699, 17.5762482701815, 0.803928010900409,
235-
1.03630968014001, 0.916600977759373, "Factor 2",
236-
0, "x6", 0.0536584940344529, 17.0821226769958, 0.375767927218761,
237-
0.741040160352204, 0.619475433557926, "Factor 3",
238-
0, "x7", 0.0695825769015842, 8.90273774186456, 0.506218568773711,
239-
0.900974372672674, 0.730948802915075, "Factor 3",
240-
0, "x8", 0.0659093164600047, 11.0902197469857, 0.498364732719689,
241-
0.860170344673322, 0.669980108781259, "Factor 3",
242-
0, "x9", 0.0650169734598685, 10.3046954222623))
243-
244-
245-
226+
list(0.712022271311838, 1.11279383173753, 0.899620313867488, "Factor 1",
227+
0, "x1", 0.101880932132255, 8.8301146744482, 0.339182433474583,
228+
0.693156723678194, 0.49794051110941, "Factor 1", 5.03185138001072e-09,
229+
"x2", 0.0851745954124038, 5.84611536689373, 0.539990088382032,
230+
0.805660643384033, 0.656156092628451, "Factor 1", 0, "x3", 0.0702283472359389,
231+
9.34318004699771, 0.856032790026097, 1.08543684864592, 0.989693449094393,
232+
"Factor 2", 0, "x4", 0.060824826209009, 16.2712088266979, 0.954112872546464,
233+
1.24054019999221, 1.10160465003145, "Factor 2", 0, "x5", 0.0610564023902934,
234+
18.042410081577, 0.803928010900409, 1.03630968014001, 0.916600977759372,
235+
"Factor 2", 0, "x6", 0.0544830064226891, 16.8236123140528, 0.37576792721876,
236+
0.741040160352204, 0.619475433557926, "Factor 3", 7.69848629289527e-11,
237+
"x7", 0.0952105063825611, 6.50637683901018, 0.50621856877371,
238+
0.900974372672673, 0.730948802915075, "Factor 3", 2.32125429988628e-12,
239+
"x8", 0.104217630469302, 7.0136770489172, 0.498364732719688,
240+
0.860170344673323, 0.669980108781259, "Factor 3", 5.52868861802835e-12,
241+
"x9", 0.0972211926575642, 6.8912969535468))
246242
})
247243

248244

0 commit comments

Comments
 (0)