Fast and Flexible Implementations of Exploratory Factor Analysis Tools
Overview
Provides a complete workflow for exploratory factor analysis (EFA). It covers data screening and factorability checks, a suite of factor retention criteria for choosing the number of factors, and factor extraction by principal axis factoring, maximum likelihood, unweighted least squares, or diagonally weighted least squares from Pearson, Spearman, Kendall, polychoric, tetrachoric, or two-stage full-information maximum likelihood correlations. A built-in rotation engine offers a range of orthogonal and oblique rotations, and standard errors for loadings and related quantities can be obtained by analytic, robust, or bootstrap methods. Further tools support model averaging across analytic choices, multigroup EFA with factor congruence, EFA on multiply imputed data, Schmid-Leiman transformation, reliability coefficients (including McDonald's omegas), factor score estimation, data simulation, and power analysis. Computationally intensive procedures are implemented in 'C++' for speed.
Comparing and Averaging Solutions
efa_compare()now savesprint(),format(), andplot()display settings, and reuses them.efa_compare()'sare_equalnow returnsNA, not0, when the compared values differ before the decimal point.efa_compare()'s elementwise differences are now signed.efa_compare(reorder = "congruence")now also matches the sign of single-factor solutions.- Fixed
efa_compare()'s handling of missing loadings. This previously inflateddiff_corresanddiff_corres_cross. - Fixed a bug that could trigger spurious warnings from
efa_average()'s progress bar.
Data Screening and Simulation
- Fixed two bugs in
efa_screen()'s outlier detection. Both could give an incorrect or less robust result. efa_screen()'s multicollinearity verdict is now based on the condition index alone, following Belsley (1991).efa_screen()now withholds an uninformative Henze-Zirkler p-value instead of reporting an exact 0 or 1.- Mardia's skewness and kurtosis in
efa_screen()now use small-sample corrections.
Show all changes in 1.1.0Hide the rest of the changes in 1.1.0
efa_simulate()gainsmissing_vars, to restrict missingness to selected variables.- Fixed
efa_simulate()'s reportedpopulationundermarginals = "VM"andforce_pd = TRUE.
Factor Retention
- The
typeargument ofefa_ekc()andekc_typeofefa_retain()no longer have any effect: the empirical Kaiser criterion now always follows Braeken and van Assen (2017). Suggested factor counts can differ from earlier results. efa_nest()results can now be plotted.efa_parallel()now shares simulated reference data between"PCA"and"SMC", roughly halving simulation time. Results for a given seed can differ from before.
Input Validation and Correlation Handling
efa_*arguments with fixed choices are now case-insensitive and accept unambiguous abbreviations.- Correlation matrices supplied as data frames are now recognised and analysed correctly.
- Correlation-matrix smoothing now consistently returns a positive-definite matrix.
Missing Data and Multiple Imputation
efa_mi()'srmsr_upperargument is deprecated and no longer used.- With
target_method = "consensus",efa_mi()'s pooled result no longer depends on the order ofdata_list. Results can differ from earlier versions. efa_mi()'s pooled RMSEA is now capped at 1, and its confidence interval is withheld when it excludes the point estimate.- An
efa_mi()solution now reports the Heywood status of each imputation, inmi_admissibility. - A
cor_method = "fiml"fit with analytic standard errors now withholds loading standard errors when the rotation is weakly determined, matching the other standard-error methods.
Model Estimation
- The
"uls"estimator now minimises the full residual, including the diagonal, matching its analytic gradient. Results can shift for over-factored models. - Starting values for the
"paf","ml", and"uls"estimators are now kept within [0, 1], matchingpsych::smc(). estimate_control()gainsfiml_max_iterandfiml_tol, to control the FIML algorithm.- A
cor_method = "fiml"fit now reports its convergence status in a newfimlcomponent, and warns if it does not converge. - An RMSEA confidence interval that cannot be computed is now reported as
NA, instead of stopping the fit.
Ordinal Correlations
- Perfectly ordered polychoric or tetrachoric pairs are now reported as
0.9999/-0.9999, with a warning. - Binary pairs with an empty response cell now use a margin-preserving continuity correction.
- Unavailable asymptotic variances for polychoric or tetrachoric pairs are now reported as
NA, and affected robust standard errors are withheld. - Rare response patterns in strongly correlated pairs are now handled more accurately. They less often block
DWLSor robust standard errors.
Power Analysis
efa_power()withgroup > 1now always solves for a whole-number sample size per group.- In simulation mode,
efa_power()now reportsNA, not a misleading hit rate, when a retention criterion never gives a suggestion. - In simulation mode,
efa_power()now rejects apthat disagrees with the population model, instead of silently replacing it.
Printed Output
- Truncated variable names that would collide in loading tables are now abbreviated and numbered, so they stay distinguishable.
print()/format()for Schmid-Leiman loading matrices now honourmax_name_length,name_style,sort_loadings, andmax_factors_per_block.
Reliability and Factor Scores
efa_reliability()andOMEGA()now compute every omega total from the model's full implied common variance, including cross-loadings and contributions from other group factors. Results can change for solutions with cross-loadings.- The whole-scale row of a correlated-factors solution is now labelled
"total", not"g"/"general", which implied a general factor such solutions do not have. efa_reliability()now recognises several solution types correctly, including Schmid-Leiman tables and single-factor solutions, which were previously misclassified, mislabeled, or refused.efa_scores()andFACTOR_SCORES()withmethod = "Bartlett"or"Anderson"now stop on a communality at or above 1, instead of returning unusable weights.efa_scores()andFACTOR_SCORES()now reject scoring data with a constant, infinite, or too-short variable, instead of silently returningNaNscores.
Rotation
- Oblique rotations, including
efa_procrustes(), now refuse a nearly singular transformation matrix at every step. Results can differ for near-degenerate solutions. - A gradient-projection rotation is now reported as converged only when its projected gradient meets tolerance. Convergence flags can differ from before.
Standard Errors
efa_fit(se = "sandwich")now withholds standard errors and confidence intervals when a Heywood case occurs.- Bootstrap output now reports the number of usable replicates when fewer than requested are available.
- Analytic standard-error output now includes factor and variable names in
SE$Phiandvcov_unrot_loadings.
From NEWS.md in the release
Install
Health
- OK13 OKNow
- OK12 OK2026-08-22
- ERROR11 OK, 1 NOTE, 1 ERROR2026-06-18
- NOTE12 OK, 2 NOTE2026-04-22
- ERROR11 OK, 2 NOTE, 1 ERROR2026-04-18
- NOTE12 OK, 2 NOTE2026-03-10
Documentation
The repository also keeps web-only articles.
- Help pages
- 113 (25 internal)includes a package overview page
- Examples that run
- 81%44 run in a plain check · 10 only when donttest examples are enabled (R CMD check --as-cran)
- Exported functions with examples
- 60%
- Documented parameters
- 89%
- Return-value docs
- 100%
- Help pages citing references
- 18%
Downloads
Repository
- PRs merged (all time)
- 75%
- Median days to close, 50 most recently updated closed issues
- 29
- Median days to close, 50 most recently updated closed PRs
- 5
Stars over time
Forks over time
Releases over time
Issues over time
PRs over time
Commits over time
10 development-tooling and community-health practices detected across 6 families in the upstream repository
Checks run against github.com/mdsteiner/efatools on 2026-10-18.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-10-17 · The repository has a site deploy workflow
pkgdown site last built 2026-10-17
Show all practicesHide 2 practices
Dependencies
Installing EFAtools adds 33 packages (16 with compiled code, 22 MB of source tarballs). Heaviest: ggplot2 6.0 MB, Rcpp 1.8 MB, GPArotation 1.6 MB.
Code & Tests
Datasets
People & History
Show 1 more contributorHide 1 contributor
Pick two releases to compare their code metrics.
- unarchivedReturned to CRAN2026-08-21
- archivedRemoved from CRAN2026-08-21issues were not corrected in time
- 1.1.0Latest
- 1.0.02026-07-23 · diff ↗ ·
added 20 exports
efa_average, efa_bartlett, efa_cd, efa_compare, efa_ekc, efa_fit, efa_hull, efa_kgc, efa_kmo, efa_map, efa_mi, efa_nest, efa_parallel, efa_procrustes, efa_retain, efa_schmid_leiman, efa_scree, efa_smt, estimate_control, rotate_control - 0.8.02026-07-07 · diff ↗ ·
removed 2 exports
%>%, CONSENSUS_PROCRUSTESadded 6 exports
efa_group, efa_power, efa_reliability, efa_scores, efa_screen, efa_simulate - 0.7.12026-05-08 · diff ↗
- 0.7.0
- RR 4.6.0 released · 2026-04-24
- 0.6.12025-07-30 · diff ↗
- 0.6.0
- 0.5.02025-05-23 · diff ↗
- RR 4.5.0 released · 2025-04-11
- 0.4.62025-03-21 · diff ↗
- 0.4.52024-12-22 · diff ↗
- RR 4.4.0 released · 2024-04-24
- RR 4.3.0 released · 2023-04-21
Show 13 earlier eventsHide 13 earlier events
- 0.4.42023-01-06 · diff ↗
- 0.4.32022-10-02 · diff ↗
- 0.4.22022-09-27 · diff ↗
- 0.4.12022-04-24 · diff ↗
- RR 4.2.0 released · 2022-04-22
- 0.4.02022-03-21 · diff ↗
- RR 4.1.0 released · 2021-05-18
- 0.3.12021-03-27 · diff ↗
- 0.3.0
- 0.2.02020-09-17 · diff ↗ ·
removed 4 exports
.factor_corres, .paf_iter, .parallel_sim, pattern:^[[:alpha:]]+added 2 exports
FACTOR_SCORES, SCREE - 0.1.1
- 0.1.02020-07-07
- RR 4.0.0 released · 2020-04-24
Package metadata
- First published
- 2020-07-07
- Total releases
- 20 / 6 yrs
- License
- GPL-3 OSI
- Minimum R
- ≥ 4.1.0
- Bundled data
- 182 KB / 16 files
- Download size
- 1.5 MB
Cite
Cite this package
Run in R for the authors' entry:
citation("EFAtools")The package provides a citation file, so citation() returns the authors' own entry.
It points to 10.21105/joss.02521.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-20, which the citation names so these numbers can be found later. More on citing and the projects behind them.