GPA | R Documentation |
Gradient projection rotation optimization routine used by various rotation objective.
GPFRSorth(A, Tmat=diag(ncol(A)), normalize=FALSE, eps=1e-5, maxit=1000,
method="varimax", methodArgs=NULL, randomStarts=0)
GPFRSoblq(A, Tmat=diag(ncol(A)), normalize=FALSE, eps=1e-5, maxit=1000,
method="quartimin", methodArgs=NULL, randomStarts=0)
GPForth(A, Tmat=diag(ncol(A)), normalize=FALSE, eps=1e-5, maxit=1000,
method="varimax", methodArgs=NULL)
GPFoblq(A, Tmat=diag(ncol(A)), normalize=FALSE, eps=1e-5, maxit=1000,
method="quartimin", methodArgs=NULL)
A |
initial factor loadings matrix for which the rotation criterian is to be optimized. |
Tmat |
initial rotation matrix. |
normalize |
see details. |
eps |
convergence is assumed when the norm of the gradient is smaller than eps. |
maxit |
maximum number of iterations allowed in the main loop. |
method |
rotation objective criterian. |
methodArgs |
a list ofmethodArgs arguments passed to the rotation objective |
randomStarts |
number of random starts (GPFRSorth and GPFRSoblq) |
Gradient projection (GP) rotation optimization routines developed by
Jennrich (2001, 2002) and Bernaards and Jennrich (2005).
These functions can be used directly
to rotate a loadings matrix, or indirectly through a rotation
objective passed to a factor estimation routine such as factanal
.
A rotation of a matrix A
is defined as A %*% solve(t(Th))
.
In case of orthogonal rotation, the factors the rotation matrix
Tmat
is orthonormal, and the rotation simplifies
to A %*% Th
. The rotation matrix Th
is computed by GP rotation.
The GPFRsorth
and GPFRSoblq
functions are the primary functions
for orthogonal and oblique rotations, respectively. These two functions
serve as wrapper functions for GPForth
and GPFoblq
, with the
added functionality of multiple random starts.
GPForth
is the main GP algorithm for orthogonal rotation.
GPFoblq
is the main GP algorithm for oblique rotation.
The GPForth
and GPFoblq
may be also be called directly.
Arguments in the wrapper functions GPFRsorth
and GPFRSoblq
are passed to GP algorithms. Functions require an initial loadings matrix
A
which fixes the equivalence class over which the optimization is done.
It must be the solution to the orthogonal factor analysis problem as obtained
from factanal
or other factor estimation routines.
The initial rotation matrix is given by the Tmat
.
By default the GP algorithm use the identity matrix as the initial rotation matrix.
For some rotation criteria local minima may exist. To start from random
initial rotation matrices, the randomStarts
argument is available
in GPFRSorth
and GPFRSoblq
. The returned object includes
the rotated loadings matrix with the lowest criterion value f
among attemnpted starts.Technically, this does not have to be the global
minimum. The randomStarts
argument
is not available GPForth
and GPFoblq
. However, for
GPForth
and GPFoblq
a single random
initial rotation matrix may be set by Tmat = Random.Start(ncol(A))
.
The argument method
can be used to specify a string indicating
the rotation objective. Oblique rotation defaults to "quartimin"
and orthogonal rotation defaults to "varimax"
. Available rotation objectives
are "oblimin"
, "quartimin"
, "target"
, "pst"
,
"oblimax"
, "entropy"
, "quartimax"
, "varimax"
,
"simplimax"
, "bentler"
, "tandemI"
, "tandemII"
,
"geomin"
, "cf"
, "infomax"
, "mccammon"
, bifactor
,
and "varimin"
. The string is prefixed with "vgQ." to give the actual function call.
See vgQ
for details.
Some rotation criteria ("oblimin"
, "target"
, "pst"
, "simplimax"
,
"geomin"
, "cf"
) require one or more additional arguments. See link{rotations}
for details and default values, if applicable.
For examples of the indirect use see rotations
.
The argument normalize
gives an indication of if and how any
normalization should be done before rotation, and then undone after rotation.
If normalize
is FALSE
(the default) no normalization is done.
If normalize
is TRUE
then Kaiser normalization is done. (So
squared row entries of normalized A
sum to 1.0. This is sometimes called
Horst normalization.)
If normalize
is a vector of length equal to the number of indicators (=
number of rows of A
) then the colums are divided by normalize
before rotation and multiplied by normalize
after rotation.
If normalize
is a function then it should take A
as an argument
and return a vector which is used like the vector above. See Nguyen and Waller (2022)
for detailed investigation of normalization on factor rotations, including
potential effect on qualitative interpretation of loadings.
A GPArotation object which is a list with elements
loadings |
The rotated loadings, one column for each factor. If randomStarts were requested then this is the rotated loadings matrix with the lowest criterion value. |
Th |
The rotation matrix, loadings %*% t(Th) = A. |
Table |
A matrix recording the iterations of the rotation optimization. |
method |
A string indicating the rotation objective function. |
orthogonal |
A logical indicating if the rotation is orthogonal. |
convergence |
A logical indicating if convergence was obtained. |
Phi |
t(Th) %*% Th. The covariance matrix of the rotated factors. This will be the identity matrix for orthogonal rotations so is omitted (NULL) for the result from GPFRSorth and GPForth. |
Gq |
The gradient of the objective function at the rotated loadings. |
randStartChar |
A vector with characteristics of random starts (GPFRSorth and GPFRSoblq only; omitted if randomStarts =< 1). |
Coen A. Bernaards and Robert I. Jennrich with some R modifications by Paul Gilbert
Bernaards, C.A. and Jennrich, R.I. (2005) Gradient Projection Algorithms and Software for Arbitrary Rotation Criteria in Factor Analysis. Educational and Psychological Measurement, 65, 676–696.
Jennrich, R.I. (2001). A simple general procedure for orthogonal rotation. Psychometrika, 66, 289–306.
Jennrich, R.I. (2002). A simple general method for oblique rotation. Psychometrika, 67, 7–19.
Nguyen, H.V. and Waller, N.G. (2022). Local minima and factor rotations in exploratory factor analysis. Psychological Methods. Advance online publication. https://doi.org/10.1037/met0000467
Random.Start
,
factanal
,
oblimin
,
quartimin
,
targetT
,
targetQ
,
pstT
,
pstQ
,
oblimax
,
entropy
,
quartimax
,
Varimax
,
varimax
,
simplimax
,
bentlerT
,
bentlerQ
,
tandemI
,
tandemII
,
geominT
,
geominQ
,
bigeominT
,
bigeominQ
,
cfT
,
cfQ
,
equamax
,
parsimax
,
infomaxT
,
infomaxQ
,
mccammon
,
varimin
,
bifactorT
,
bifactorQ
,
promax
# see rotations for more examples
data(Harman, package = "GPArotation")
GPFRSorth(Harman8, method = "quartimax")
quartimax(Harman8)
GPFRSoblq(Harman8, method = "quartimin", normalize = TRUE)
loadings( quartimin(Harman8, normalize = TRUE) )
# using random starts
data("WansbeekMeijer", package = "GPArotation")
fa.unrotated <- factanal(factors = 3, covmat=NetherlandsTV, normalize=TRUE, rotation="none")
GPFRSoblq(loadings(fa.unrotated), normalize = TRUE, method = "oblimin", randomStarts = 100)
oblimin(loadings(fa.unrotated), randomStarts=100)
data(Thurstone, package = "GPArotation")
geominQ(box26, normalize = TRUE, randomStarts=100)
# displaying results of factor analysis rotation output
origdigits <- options("digits")
Abor.unrotated <- factanal(factors = 2, covmat = ability.cov, rotation = "none")
Abor <- oblimin(loadings(Abor.unrotated), randomStarts = 20)
Abor
print(Abor)
print(Abor, sortLoadings=FALSE) #this matches the output passed to factanal
print(Abor, Table=TRUE)
print(Abor, rotateMat=TRUE)
print(Abor, digits=2)
# by default provides the structure matrix for oblique rotation
summary(Abor)
summary(Abor, Structure=FALSE)
options(digits = origdigits$digits)
# GPArotation output does sort loadings, but use print to obtain if needed
set.seed(334)
xusl <- quartimin(Harman8, normalize = TRUE, randomStarts=100)
# loadings without ordering (default)
loadings(xusl)
max(abs(print(xusl)$loadings - xusl$loadings)) == 0 # FALSE
# output sorted loadings via print (not default)
xsl <- print(xusl)
max(abs(print(xsl)$loadings - xsl$loadings)) == 0 # TRUE
# Kaiser normalization is used when normalize=TRUE
factanal(factors = 2, covmat = ability.cov, rotation = "oblimin",
control=list(rotate=list(normalize = TRUE)))
# Cureton-Mulaik normalization can be done by passing values to the rotation
# may result in convergence problems
NormalizingWeightCM <- function (L) {
Dk <- diag(sqrt(diag(L %*% t(L)))^-1) %*% L
wghts <- rep(0, nrow(L))
fpls <- Dk[, 1]
acosi <- acos(ncol(L)^(-1/2))
for (i in 1:nrow(L)) {
num <- (acosi - acos(abs(fpls[i])))
dem <- (acosi - (function(a, m) ifelse(abs(a) < (m^(-1/2)), pi/2, 0))(fpls[i], ncol(L)))
wghts[i] <- cos(num/dem * pi/2)^2 + 0.001
}
Dv <- wghts * sqrt(diag(L %*% t(L)))^-1
Dv
}
quartimin(Harman8, normalize = NormalizingWeightCM(Harman8), randomStarts=100)
quartimin(Harman8, normalize = TRUE, randomStarts=100)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.