# GPA: Rotation Optimization In GPArotation: Gradient Projection Factor Rotation

 GPA R Documentation

## Rotation Optimization

### Description

Gradient projection rotation optimization routine used by various rotation objective.

### Usage

``````    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)
``````

### Arguments

 `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)

### Details

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.

### Value

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).

### Author(s)

Coen A. Bernaards and Robert I. Jennrich with some R modifications by Paul Gilbert

### References

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`

### Examples

``````  # see rotations for more examples

data(Harman, package = "GPArotation")
GPFRSorth(Harman8, method = "quartimax")
quartimax(Harman8)
GPFRSoblq(Harman8, method = "quartimin", normalize = TRUE)

# using random starts
data("WansbeekMeijer", package = "GPArotation")
fa.unrotated  <- factanal(factors = 3, covmat=NetherlandsTV, normalize=TRUE, rotation="none")
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
print(Abor)
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)
xsl <- print(xusl)

# 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)

``````

GPArotation documentation built on May 29, 2024, 8:16 a.m.