NEWS
latentFactoR 0.0.9 (2026-09-07)
- UPDATE: skew range supported by 'categorize', 'simulate_factors', and 'simulate_hierarchical_factors' expanded from -2/2 to -10/10 (in increments of 0.05); 'skew_tables' regenerated over the new range
- INTERNAL: ‘skew_generator' rewritten to compute skewness analytically from category counts instead of materializing a 'sample_size'-length vector and calling 'psych::skew()' on it (mathematically equivalent, since the moment-skewness formula only depends on counts per value); it also now searches adaptively over 'reduction_factor' and 'sample_size' when the defaults can’t reach a target skew directly, closing gaps (e.g., skew near zero for 'categories >= 4') that were previously unreachable regardless of tolerance. Together, this cut full skew-table generation time from tens of minutes to about a second
- FIX: ‘skew_generator'’s bisection search had a typo ('limitinf' instead of 'limitsinf') that left the lower search bound frozen at zero, which combined with 'skew(proportion)' not being monotonic across its full domain, could prevent convergence even for reachable targets
latentFactoR 0.0.8 (2026-07-28)
- ADD: ‘simulate_hierarchical_factors' simulates data from a hierarchical (second-order) factor model, where variables load onto lower-order factors and lower-order factors load onto higher-order factors; the lower-order factors’ residual (disturbance) structure can be set directly via 'off_disturbances'/'off_disturbances_range' (only their *off-diagonal*, correlated-disturbance elements are settable — the diagonal is always rescaled to unit variance, since any unexplained variance is normalized away regardless) or left to be implied instead by supplying a target 'lower_correlations'/'lower_correlations_range' matrix
- ADD: 'print'/'summary' methods for 'simulate_factors'/'simulate_hierarchical_factors' output, reporting loadings, correlations, disturbances, categories, and skew
- FIX: 'simulate_factors' could loop indefinitely when supplied 'loadings'/'correlations' were jointly inadmissible; now errors after 1000 attempts with an informative message
- INTERNAL: consolidated '@import'/'@importFrom' roxygen tags into a single package-level block in 'latentFactoR.R'
- INTERNAL: cleaned up and optimized code in 'simulate_factors'
- INTERNAL: random number generation moved to C
- INTERNAL: cleaned up and optimized code in 'add_cross_loadings', 'add_local_dependence', 'add_method_factors', 'add_population_error', and 'add_wording_effects' to match 'simulate_factors' (uses C-based random number generation)
- FIX: 'add_cross_loadings' could error with "missing value where TRUE/FALSE needed" when a factor was randomly assigned zero cross-loadings (e.g., via 'proportion_cross_loadings_range')
- FIX: 'proportion_negative_range' in 'add_method_factors' was documented but not implemented; it now works as documented
- FIX: documentation in 'simulate_factors' was missing the 'continuous_data' return value and the 'cross_loadings'/'categorical_limit' parameters list, and had the loadings matrix dimensions reversed
- FIX: 'simulate_factors'/'simulate_hierarchical_factors' misassigned per-variable 'skew' values to the wrong columns whenever a full-length 'skew' vector was supplied on a model mixing categorical and continuous variables
- FIX: 'simulate_factors'/'simulate_hierarchical_factors' ignored 'loadings_range'/'correlations_range' (and the hierarchical equivalents) after the first retry attempt, so the admissibility retry loop could never actually resample those parameters
- FIX: 'add_cross_loadings' could error with "missing value where TRUE/FALSE needed" when 'magnitude_cross_loadings' was supplied with length equal to 'factors' (a documented, valid length)
- FIX: 'add_cross_loadings' now errors informatively (instead of crashing) when called on data with only one factor, since cross-loadings require at least two factors
- FIX: ‘add_local_dependence' could error with "NAs are not allowed in subscripted assignments" when composed after 'add_cross_loadings' had already consumed most of a factor’s available variables
- FIX: 'add_cross_loadings'/'add_local_dependence'/'add_method_factors'/'add_wording_effects' incorrectly indexed 'parameters$variables' when converting a raw-count '_range' argument (e.g. 'proportion_cross_loadings_range') into a proportion, which could silently misconvert the range or crash outright for a single-factor model
- FIX: 'add_local_dependence'/'add_method_factors' admissibility retry loops had no maximum-iteration guard and could loop indefinitely
- FIX: 'add_population_error' reused the first random population-error draw on every retry iteration instead of resampling, making 'convergence_iterations' ineffective
- FIX: ‘add_population_error' applied its CFA sign-indeterminacy correction globally across the whole loadings matrix instead of per-factor, which could corrupt an otherwise correctly-signed factor’s loadings in multi-factor models
- FIX: 'ESEM' did not resolve its 'estimator' argument via 'match.arg', so the documented default (omitting 'estimator') failed; 'estimator' now defaults to '"MLR"'
- FIX: 'ESEM' built lavaan variable names with a hardcoded zero-padding width that mismatched the actual data column names for models with fewer than 10 or 100+ total variables
- FIX: 'NEST'/'factor_forest'/'estimate_dimensions' used base 'isSymmetric()' (which requires matching row and column names) to detect correlation-matrix input; an unnamed but valid correlation matrix was misclassified as raw data, silently discarding a user-supplied 'sample_size'
- FIX: 'NEST' could error with a non-conformable matrix multiplication when its internal rank-reduction step truncated below the requested number of factors
- FIX: 'EKC' returned 'NA' instead of the maximum number of dimensions when every eigenvalue exceeded its reference value
- FIX: 'obtain_zipfs_parameters' could not recover 'alpha < 1' due to a hardcoded search floor, despite 'alpha < 1' being a documented, valid input to 'data_to_zipfs'
- FIX: ‘data_to_zipfs'’s zero-sum-column repair silently failed when the most-correlated donor column was itself all-zero
- FIX: ‘factor_forest'’s downloaded model cache path used a Windows-style backslash separator, breaking cache detection (forcing re-download every call) on Linux/macOS
- FIX: ‘factor_forest'’s eigenvalue-padding step could run backward and overwrite real eigenvalues for datasets with 80 or more variables
- FIX: 'simulate_factors' enforced a minimum of 2 variables per factor in code while documenting (and enforcing via 'variables_range') a minimum of 3
- INTERNAL: removed dead/unreachable code ('error.report', a duplicated 'digits()' definition, a non-functional '.onload' typo) and added 'URL'/'BugReports' to 'DESCRIPTION'; 'inst/CITATION' now derives its version/year from 'DESCRIPTION' instead of a hardcoded string
latentFactoR 0.0.7 (2025-11-03)
- FIX: error check for positive definite in 'add_population_error'
- FIX: correction when adding negative skew for continuous data (internal function: 'skew_continuous')
- UPDATE: better ML population error in 'add_population_error' (update from {bifactor})
- UPDATE: some optimizations to 'add_population_error'
- UPDATE: some optimiztaions to 'NEST'
latentFactoR 0.0.6 (2024-04-18)
- MOVE: 'add_wording_effects' methods moved from 'utils-latentFactoR' to 'add_wording_effects-helpers' to facilitate ease of finding code (no observable changes to the user)
- FIX: categories greater than 7 were not previously allowed (they are now)
- FIX: correlations in 'EKC' were not used appropriately and led to an error
- UPDATE: switched on "Byte-Compile" (byte-compiles on our end and not when the user installs)
latentFactoR 0.0.5
- FIX: bug in skew when only providing 1 value
- FIX: further correction to 'EKC' (uses 'cumsum(eigenvalues)' rather than 'sum(eigenvalues)')
- ADD: 'add_wording_effects' will add wording effects such as acquiescence, difficulty, random careless, straight line, or some combination of the four to a simulated factor model
- ADD: 'ESEM' to perform Exploratory Structural Equation Modeling using {lavaan} (allows wording effects to be estimated)
- FIX: 'factor_forest' uses raw data in 'psych::fa.parallel' rather than correlation matrix
- ADD: internal functions for computing effect sizes across conditions are included (see 'simulation_helpers.R')
- ADD: skew in 'add_local_dependence' is guaranteed to be same direction for locally dependent variables
latentFactoR 0.0.4 (2022-11-22)
- FIX: correction to ‘EKC' (used 'factor_forest'’s version of EKC which used reference values rather than eigenvalues); 'EKC' uses eigenvalues whereas 'factor_forest' uses reference (which was what the random forest model was trained on)
- FIX: cross-loadings with population error are screened for communalities >= 0.80; communalities near 0.90 prior to population error would often get stuck and not converge
- ADD: 'skew' argument for continuous data
latentFactoR 0.0.3 (2022-10-13)
- ADD: 'add_population_error' will add population error, using {bifactor}, to a simulated factor model
- ADD: ‘data_to_zipfs' to transform data to Zipf’s distribution from 'simulate_factors'
- ADD: ‘obtain_zipfs_parameters' to obtain a dataset’s best fitting Zipf's distribution parameters
- ADD: 'NEST' Next Eigenvalue Sufficiency Test to estimate dimensions
- ADD: 'estimate_dimensions' provides a single function to estimate dimensions using state-of-the-art methods: Exploratory Graph Analysis (EGA),
Exploratory Factor Analysis with out-of-sample prediction (FSPE), Next Eigenvalue Sufficiency Test (NEST), parallel analysis (PA), and Factor Forest
latentFactoR 0.0.2 (2022-09-09)
- UPDATE: skews for categories now include 6 categories
- UPDATE: available skew increments are now 0.05 (were 0.50 previously)
- ADD: 'add_local_dependence' will add local dependence between variables from a simulated factor model
Initial commit version 0.0.1