View source: R/efa_procrustes.R
| efa_procrustes | R Documentation |
efa_procrustes() aligns one loading matrix to a target loading matrix with the
same dimensions. It is used internally by efa_mi(), but can also be used
directly when factor columns must be brought into a common orientation before
averaging or comparing solutions.
efa_procrustes(
A,
Target,
rotation = c("orthogonal", "oblique"),
S = NULL,
T_init = NULL,
oblique_eps = 1e-05,
oblique_maxit = 1000,
oblique_max_line_search = 10,
oblique_step0 = 1,
oblique_normalize = FALSE,
oblique_random_starts = 0,
oblique_screen_keep = 2,
oblique_triage_maxit = 25,
oblique_triage_improve_tol = 0
)
A |
Numeric loading matrix to be aligned. |
Target |
Numeric target matrix with the same dimensions as |
rotation |
Character string, either |
S |
Optional |
T_init |
Optional |
oblique_eps |
Positive convergence tolerance for the projected-gradient norm in the oblique solver. |
oblique_maxit |
Non-negative integer. Maximum number of projected-gradient updates in the full oblique solver. |
oblique_max_line_search |
Non-negative integer. Maximum number of step-halving attempts after the initial line-search step. |
oblique_step0 |
Positive initial step size for the oblique solver. |
oblique_normalize |
Logical; if |
oblique_random_starts |
Non-negative integer. Number of additional random starts used by the oblique solver. |
oblique_screen_keep |
Non-negative integer. Number of random starts retained after cheap objective screening and sent to triage optimization. |
oblique_triage_maxit |
Non-negative integer. Number of short optimization iterations used in the triage stage. |
oblique_triage_improve_tol |
Non-negative scalar. Relative improvement required for a triaged start to be promoted to full optimization. |
For rotation = "orthogonal", the function solves the closed-form orthogonal
Procrustes problem
\min_T \frac{1}{2}\|A T - B\|_F^2 \quad \textrm{subject to}\quad T'T = I,
where A is the loading matrix and B is Target.
For rotation = "oblique", the function calls the compiled
.oblique_procrustes() optimizer. The oblique convention is the same as in
GPArotation::targetQ():
L = A T^{-T}, \qquad \Phi = T'T, \qquad diag(\Phi) = 1.
By default the oblique solver is warm-started from the closed-form orthogonal
Procrustes solution, which resolves the factor permutation and sign
indeterminacy and avoids the poor local minima an identity start can fall
into. Supply T_init to override this start. Random starts are only used for
oblique alignment. For one-factor models, oblique and orthogonal alignment are
equivalent, so the function uses the stable one-factor orthogonal solution
instead of calling the oblique optimizer.
A list. Every path returns the following components:
loadings |
Aligned loading matrix. |
T |
Transformation matrix. |
Phi |
Factor intercorrelation matrix; the identity for orthogonal and one-factor alignment. |
value |
Target criterion at the returned solution. |
convergence |
Logical; |
valid |
Logical; whether the transformation defines an admissible |
iterations |
Number of solver iterations; |
kappa_T |
Condition number of |
Table |
Iteration history with columns |
method |
|
line_search_failed |
Logical line-search diagnostic. |
best_start_index, all_start_indices, all_values, all_converged, all_iterations |
Multi-start summary of the starts that were fully optimized; each has a single entry when no random starts were used. |
The oblique solver additionally returns screen_start_indices and
screen_values (the starts kept by cheap objective screening and their
criterion values) together with the counts n_random_starts, n_screened,
n_triaged, and n_fully_optimized. These six components are absent for
rotation = "orthogonal" and for one-factor models, which are aligned with the
orthogonal solution.
Row and column names are preserved where possible. When
oblique_normalize = TRUE the returned loadings are back-transformed to the
original scale, but value is the criterion on the Kaiser-normalized loadings,
so it is not 0.5 * sum((loadings - Target)^2).
Other factor rotation:
efa_schmid_leiman()
## Align an estimated loading matrix to a known target pattern: fit an
## unrotated three-factor model, then rotate its loadings toward the true
## population pattern.
efa_mod <- efa_fit(test_models$baseline$cormat, N = 500, n_factors = 3,
estimator = "PAF", rotation = "none")
target <- population_models$loadings$baseline
## Orthogonal target rotation (rigid rotation/reflection):
efa_procrustes(efa_mod$unrot_loadings, target, rotation = "orthogonal")
## Oblique target rotation (lets the aligned factors correlate):
efa_procrustes(efa_mod$unrot_loadings, target, rotation = "oblique")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.