Get started with fit indices
Source:vignettes/get-started-fit-indices.Rmd
get-started-fit-indices.RmdGoal
By the end of this guide, you will be able to:
- Fit a CFA model with
lavaan. - Extract fit indices with
model_fit(). - Compare alternative estimators with
compare_model_fit(). - Fit an ordinal-item version with
WLSMVandordered = TRUE.
Step 1: Fit a baseline CFA model
model <- '
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9
'
fit_mlr <- cfa(
model,
data = HolzingerSwineford1939,
estimator = "MLR"
)Step 2: Extract fit indices
model_fit(fit_mlr)
#> NOBS | ESTIMATOR | NPAR | Chi2(24) | p (Chi2) | CFI | TLI | RMSEA
#> ---------------------------------------------------------------------
#> 301 | MLR | 21 | 87.13 | < .001 | 0.925 | 0.888 | 0.093
#>
#> NOBS | RMSEA CI | SRMR
#> -----------------------------
#> 301 | [0.073, 0.115] | 0.065Request only selected metrics when needed:
Step 3: Compare two fitted models
fit_ulsm <- cfa(
model,
data = HolzingerSwineford1939,
estimator = "ULSM"
)
compare_model_fit(MLR = fit_mlr, ULSM = fit_ulsm)
#> MODEL | NOBS | ESTIMATOR | NPAR | Chi2(24) | p (Chi2) | CFI | TLI | RMSEA
#> -----------------------------------------------------------------------------
#> MLR | 301 | MLR | 21 | 87.13 | < .001 | 0.925 | 0.888 | 0.093
#> ULSM | 301 | ULSM | 21 | 90.60 | < .001 | 0.931 | 0.897 | 0.096
#>
#> MODEL | RMSEA CI | SRMR
#> ------------------------------
#> MLR | [0.073, 0.115] | 0.065
#> ULSM | [0.073, 0.120] | 0.059Step 4: Ordinal example with WLSMV
(ordered = TRUE)
This example converts the nine Holzinger-Swineford items
(x1 to x9) into four ordered categories, then
fits the same CFA model with WLSMV.
item_names <- paste0("x", 1:9)
ordered_data <- HolzingerSwineford1939
ordered_data[item_names] <- lapply(
ordered_data[item_names],
function(x) ordered(cut(x, breaks = 4, include.lowest = TRUE))
)
fit_wlsmv <- cfa(
model,
data = ordered_data,
estimator = "WLSMV",
ordered = TRUE
)
model_fit(fit_wlsmv)
#> NOBS | ESTIMATOR | NPAR | Chi2(24) | p (Chi2) | CFI | TLI | RMSEA
#> ---------------------------------------------------------------------
#> 301 | WLSMV | 39 | 63.89 | < .001 | 0.969 | 0.954 | 0.074
#>
#> NOBS | RMSEA CI | SRMR
#> -----------------------------
#> 301 | [0.053, 0.097] | 0.066
compare_model_fit(MLR = fit_mlr, WLSMV = fit_wlsmv)
#> MODEL | NOBS | ESTIMATOR | NPAR | Chi2(24) | p (Chi2) | CFI | TLI | RMSEA
#> -----------------------------------------------------------------------------
#> MLR | 301 | MLR | 21 | 87.13 | < .001 | 0.925 | 0.888 | 0.093
#> WLSMV | 301 | WLSMV | 39 | 63.89 | < .001 | 0.969 | 0.954 | 0.074
#>
#> MODEL | RMSEA CI | SRMR
#> ------------------------------
#> MLR | [0.073, 0.115] | 0.065
#> WLSMV | [0.053, 0.097] | 0.066Common pitfalls
- When using robust estimators, metric names may map to scaled/robust variants.
- Keep model names explicit (
MLR,ULSM, etc.) for clearer comparison tables. - This ordinal recoding is only a didactic example; use substantively justified category definitions in real analyses.
Next steps
- Continue with SEM and parameter estimates.
- See full API details in the Reference.