## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 7,
  fig.align = "center"
)

# The multiple-imputation section uses mice to create the imputations. It is only
# suggested by the package, so the imputation chunks are evaluated only when it is
# installed.
mice_ok <- requireNamespace("mice", quietly = TRUE)

## -----------------------------------------------------------------------------
library(EFAtools)

## -----------------------------------------------------------------------------
Lambda <- population_models$loadings$baseline  # 18 x 3 loading pattern
Phi    <- population_models$phis_3$moderate    # moderate factor intercorrelations

## -----------------------------------------------------------------------------
d_ord <- efa_simulate(N = 400, Lambda = Lambda, Phi = Phi,
                      categories = 4, match = "polychoric", seed = 2024)$data
d_ord[1:5, 1:6]

## ----warning = FALSE----------------------------------------------------------
efa_screen(d_ord, seed = 42)

## -----------------------------------------------------------------------------
efa_poly <- efa_fit(d_ord, n_factors = 3, cor_method = "poly", estimator = "dwls",
                    rotation = "oblimin", se = "sandwich")
efa_poly

## -----------------------------------------------------------------------------
round(efa_poly$SE$rot_loadings, 3)

## -----------------------------------------------------------------------------
efa_cont <- efa_fit(d_ord, n_factors = 3, cor_method = "pearson", estimator = "ML",
                    rotation = "oblimin")

cmp <- efa_compare(efa_poly$rot_loadings, efa_cont$rot_loadings,
                   x_labels = c("Polychoric / DWLS", "Pearson / ML"))
cmp
plot(cmp)

## -----------------------------------------------------------------------------
d_miss <- efa_simulate(N = 250, Lambda = Lambda, Phi = Phi,
                       missing = "MAR", missing_prop = 0.15,
                       missing_vars = 1:9, missing_predictor = 10:18,
                       seed = 2024)$data
round(mean(is.na(d_miss)), 3)          # overall proportion missing
round(colMeans(is.na(d_miss)), 3)      # holed items only

## -----------------------------------------------------------------------------
efa_fiml <- efa_fit(d_miss, n_factors = 3, cor_method = "fiml", estimator = "ml",
                    rotation = "oblimin")
efa_fiml

## -----------------------------------------------------------------------------
sum(complete.cases(d_miss))    # cases a score can be formed for

## ----eval = mice_ok-----------------------------------------------------------
imp <- mice::mice(as.data.frame(d_miss), m = 5, method = "norm",
                  printFlag = FALSE, seed = 123)
dat_list <- lapply(seq_len(imp$m), function(i) mice::complete(imp, i))

## ----eval = mice_ok-----------------------------------------------------------
efa_pooled <- efa_mi(dat_list, n_factors = 3, estimator = "ml", rotation = "oblimin")
efa_pooled

## -----------------------------------------------------------------------------
d_ord_miss <- efa_simulate(N = 300, Lambda = Lambda, Phi = Phi,
                           categories = 4, match = "polychoric",
                           missing = "MCAR", missing_prop = 0.08, seed = 2024)$data

round(mean(is.na(d_ord_miss)), 3)     # overall proportion missing
sum(complete.cases(d_ord_miss))       # respondents who answered every item

## -----------------------------------------------------------------------------
efa_ord_miss <- efa_fit(d_ord_miss, n_factors = 3, cor_method = "poly",
                        estimator = "dwls", rotation = "oblimin")
efa_ord_miss$settings$N        # cases the fit is actually based on

## ----error = TRUE-------------------------------------------------------------
try({
efa_fit(d_ord_miss, n_factors = 3, cor_method = "fiml", estimator = "dwls")
})

## ----eval = mice_ok-----------------------------------------------------------
imp_ord <- mice::mice(as.data.frame(d_ord_miss), m = 5, method = "pmm",
                      printFlag = FALSE, seed = 123)
dat_ord <- lapply(seq_len(imp_ord$m), function(i) mice::complete(imp_ord, i))

efa_ord_pooled <- efa_mi(dat_ord, n_factors = 3, cor_method = "poly",
                         estimator = "dwls", rotation = "oblimin")
efa_ord_pooled

