| lp | R Documentation |
L^p RotationPerforms L^p rotation to obtain sparse factor loadings.
GPForth.lp(A, Tmat = diag(ncol(A)), p = 1, normalize = FALSE, eps = 1e-05,
maxit = 10000, gpaiter = 5)
GPFoblq.lp(A, Tmat = diag(ncol(A)), p = 1, normalize = FALSE, eps = 1e-05,
maxit = 10000, gpaiter = 5)
A |
Initial factor loadings matrix to be rotated. |
Tmat |
Initial rotation matrix. |
p |
Component-wise |
normalize |
Not recommended for |
eps |
Convergence is assumed when the norm of the gradient is smaller
than |
maxit |
Maximum number of iterations allowed in the main loop. |
gpaiter |
Maximum iterations for the inner GPA rotation loop. The goal is to decrease the objective value, not fully optimize the inner loop. Warnings may appear but can be ignored if the main loop converges. |
These functions optimize an L^p rotation objective where
0 < p <= 1. A smaller value of p promotes greater sparsity
in the loading matrix but increases computational difficulty. For
guidance on choosing p, see the Concluding Remarks in
Liu et al. (2023).
The user-facing wrapper functions lpT and lpQ
provide random start functionality on top of GPForth.lp and
GPFoblq.lp respectively, analogous to how GPFRSorth
and GPFRSoblq wrap GPForth and GPFoblq for
standard rotation criteria. For most users lpT and lpQ
are the recommended entry points.
Since the L^p objective is nonsmooth, a different optimization
method is required compared to smooth rotation criteria. GPForth.lp
and GPFoblq.lp replace GPForth and GPFoblq for
orthogonal and oblique L^p rotations, respectively.
The optimization uses an iterative reweighted least squares (IRLS) approach.
The nonsmooth objective is approximated by a smooth weighted least squares
function in the outer loop, which is then optimized using GPA in the inner
loop (gpaiter controls the maximum inner iterations).
Normalization is not recommended for L^p rotation and may
produce unexpected results.
A GPArotation object, which is a list containing:
loadings |
Rotated loadings matrix, with one column per factor. |
Th |
Rotation matrix, satisfying |
Table |
Data frame recording iteration details: iteration count, objective value, and elapsed time. |
method |
String indicating the rotation objective function. |
orthogonal |
Logical indicating whether the rotation is orthogonal. |
convergence |
Logical indicating whether convergence was achieved.
Convergence is assessed element-wise using |
Phi |
Covariance matrix of rotated factors, |
Xinyi Liu, with minor modifications for GPArotation by C. Bernaards.
Liu, X., Wallin, G., Chen, Y., and Moustaki, I. (2023). Rotation to
sparse loadings using L^p losses and related inference
problems. Psychometrika, 88(2), 527–553.
doi: 10.1007/s11336-023-09911-y
lpT,
lpQ,
vgQ.lp.wls
data("WansbeekMeijer", package = "GPArotation")
fa.unrotated <- factanal(factors = 2, covmat = NetherlandsTV, rotation = "none")
options(warn = -1)
# Orthogonal rotation — single start
fa.lpT1 <- GPForth.lp(loadings(fa.unrotated), p = 1)
# Orthogonal rotation — 10 random starts
fa.lpT <- lpT(loadings(fa.unrotated), Tmat = Random.Start(2), p = 1,
randomStarts = 10)
print(fa.lpT, digits = 5, sortLoadings = FALSE, Table = TRUE, rotateMat = TRUE)
# Oblique rotation — single start
fa.lpQ1 <- GPFoblq.lp(loadings(fa.unrotated), p = 1)
# Oblique rotation — 10 random starts
fa.lpQ <- lpQ(loadings(fa.unrotated), p = 1, randomStarts = 10)
summary(fa.lpQ, Structure = TRUE)
# Compare Lp (p=1), Lp (p=0.5), and Geomin oblique rotations
set.seed(1020)
fa.lpQ1 <- lpQ(loadings(fa.unrotated), p = 1, randomStarts = 10)
fa.lpQ0.5 <- lpQ(loadings(fa.unrotated), p = 0.5, randomStarts = 10)
fa.geo <- geominQ(loadings(fa.unrotated), randomStarts = 10)
# With factor ordering using internal sortGPALoadings helper
res <- round(cbind(GPArotation:::.sortGPALoadings(fa.lpQ1)$loadings,
GPArotation:::.sortGPALoadings(fa.lpQ0.5)$loadings,
GPArotation:::.sortGPALoadings(fa.geo)$loadings), 3)
print(c("oblique -- Lp p=1 Lp p=0.5 Geomin"))
print(res)
# Without factor ordering
res <- round(cbind(fa.lpQ1$loadings, fa.lpQ0.5$loadings, fa.geo$loadings), 3)
print(c("oblique -- Lp p=1 Lp p=0.5 Geomin"))
print(res)
options(warn = 0)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.