---
title: "Complete continuous-data models"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Complete continuous-data models}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  message = FALSE,
  warning = FALSE
)
```

## Scope

This guide covers models with continuous, complete data. Normal-theory maximum
likelihood is the most thoroughly studied part of `semTests` and offers the
widest menu of test options. Complete-data GLS and ULS are supported too, and
their results have been checked against a separate implementation.

```{r setup}
library("semTests")
library("lavaan")

model <- "
  visual  =~ x1 + x2 + x3
  textual =~ x4 + x5 + x6
  speed   =~ x7 + x8 + x9
"
data <- HolzingerSwineford1939
```

## Overall goodness of fit

Ask lavaan for a robust test when fitting the model. This stores the extra
sample information that `semTests` needs.

```{r ml-fit}
fit_ml <- cfa(model, data, estimator = "MLM")
pvalues(fit_ml)
```

The default uses penalized eigenvalue block averaging. You can also request a
small collection of tests in one call:

```{r ml-battery}
pvalues(
  fit_ml,
  c("STD_ML", "SB_ML", "SS_ML", "ALL_ML", "PEBA4_ML")
)
```

The names let you choose three ingredients:

* the p-value method, such as `SB`, `SS`, `ALL`, or `PEBA4`
* the usual gamma estimate or the unbiased Du--Bentler estimate, selected with
  `UG`
* the standard statistic, selected with `ML`, or Browne's reweighted statistic,
  selected with `RLS`

The unbiased gamma and RLS statistic are available for continuous,
complete-data fits from lavaan's ML family, including `MLM` and `MLR` fits:

```{r classical-options}
pvalues(
  fit_ml,
  c("SB_UG_ML", "PEBA4_UG_ML", "PEBA4_RLS", "PEBA4_UG_RLS")
)
```

## Reading the result

The printed footer records what was actually used. The same information is
available programmatically:

```{r provenance}
result <- pvalues(fit_ml, "PEBA4_ML")
attr(result, "semtests")
```

That record is useful when several kinds of models end up in the same
analysis.

## Nested comparison

The constrained model goes first. Here two loading equalities are tested
jointly:

```{r nested-fit}
constrained <- "
  visual  =~ x1 + a*x2 + a*x3
  textual =~ x4 + b*x5 + b*x6
  speed   =~ x7 + x8 + x9
"

m1 <- cfa(model, data, estimator = "MLM")
m0 <- cfa(constrained, data, estimator = "MLM")

pvalues_nested(m0, m1)
```

Satorra's 2000 reduction is the method used for nested comparison:

```{r nested-methods}
pvalues_nested(m0, m1, method = "2000", tests = c("SB_ML", "PALL_ML"))
```

`PALL` is the recommended default for nested comparison. The Satorra--Bentler
2001 construction has been withdrawn because it performs poorly, so
`method = "2001"` points you back to `"2000"`.

## GLS and ULS

GLS supplies the required sample information directly. For ULS, ask lavaan for
a robust test so that it computes the same ingredient:

```{r least-squares}
fit_gls <- cfa(model, data, estimator = "GLS")
fit_uls <- cfa(
  model, data,
  estimator = "ULS", test = "satorra.bentler"
)

pvalues(fit_gls, "PEBA4")
pvalues(fit_uls, "PEBA4")
```

For GLS and ULS, use the standard statistic and the usual biased gamma. `RLS`
and `UG` are limited to the complete-data ML setting.

## Practical checks

A quick check on these points catches most avoidable problems:

1. Inspect convergence and admissibility. `semTests` refuses nonconvergence and
   warns when lavaan's post-estimation check fails.
2. Request a robust lavaan test whenever the fit would otherwise omit `Gamma`.
3. Report the test name, statistic, and gamma choice.
4. Keep the `semtests` attribute with saved results.
5. Make sure nested models really are nested. `semTests` checks that the fits
   use comparable data and options, while the model logic is still yours.

See `vignette("categorical-data", package = "semTests")` and
`vignette("fiml-missing-data", package = "semTests")` before carrying this
workflow to categorical or missing data.

## References

Browne, M. W. (1974). Generalized least squares estimators in the analysis of
covariance structures. *South African Statistical Journal*, 8, 1–24.

Du, H., & Bentler, P. M. (2022). 40-Year Old Unbiased Distribution Free
Estimator Reliably Improves SEM Statistics for Nonnormal Data. *Structural
Equation Modeling*, 29(6), 872–887.
<https://doi.org/10.1080/10705511.2022.2063870>

Foldnes, N., Moss, J., & Grønneberg, S. (2025). Improved goodness of fit
procedures for structural equation models. *Structural Equation Modeling: A
Multidisciplinary Journal*, 32(1), 1–13.
<https://doi.org/10.1080/10705511.2024.2372028>

Foldnes, N., Grønneberg, S., & Moss, J. (2026). Penalized eigenvalue block
averaging: Extension to nested model comparison and Monte Carlo evaluations.
*Behavior Research Methods*, 58, article 107.
<https://doi.org/10.3758/s13428-026-02968-4>

Satorra, A. (2000). Scaled and adjusted restricted tests in multi-sample
analysis of moment structures. In R. D. H. Heijmans, D. S. G. Pollock, &
A. Satorra (Eds.), *Innovations in Multivariate Statistical Analysis*
(pp. 233–247). Kluwer Academic.
<https://doi.org/10.1007/978-1-4615-4603-0_17>

Satorra, A., & Bentler, P. M. (2001). A scaled difference chi-square test
statistic for moment structure analysis. *Psychometrika*, 66(4), 507–514.
<https://doi.org/10.1007/BF02296192>
