Rotations Functions Using Gradient Projection Algorithms
rotations.RdOptimize factor loading rotation objective.
Usage
oblimin(A, Tmat=diag(ncol(A)), gam=0, normalize=FALSE, randomStarts=0, ...)
quartimin(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
targetT(A=NULL, Tmat=diag(ncol(A)), Target=NULL, normalize=FALSE, eps=1e-5,
maxit=1000, randomStarts=0, L=NULL, ...)
targetQ(A=NULL, Tmat=diag(ncol(A)), Target=NULL, normalize=FALSE, eps=1e-5,
maxit=1000, randomStarts=0, L=NULL, ...)
pstT(A=NULL, Tmat=diag(ncol(A)), W=NULL, Target=NULL, normalize=FALSE, eps=1e-5,
maxit=1000, randomStarts=0, L=NULL, ...)
pstQ(A=NULL, Tmat=diag(ncol(A)), W=NULL, Target=NULL, normalize=FALSE, eps=1e-5,
maxit=1000, randomStarts=0, L=NULL, ...)
oblimax(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
entropy(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
quartimax(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
Varimax(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
simplimax(A, Tmat=diag(ncol(A)), k=nrow(A), normalize=FALSE, randomStarts=0, ...)
bentlerT(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
bentlerQ(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
tandemI(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
tandemII(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
geominT(A, Tmat=diag(ncol(A)), delta=0.01, normalize=FALSE, randomStarts=0, ...)
geominQ(A, Tmat=diag(ncol(A)), delta=0.01, normalize=FALSE, randomStarts=0, ...)
bigeominT(A, Tmat=diag(ncol(A)), delta=0.01, normalize=FALSE, randomStarts=0, ...)
bigeominQ(A, Tmat=diag(ncol(A)), delta=0.01, normalize=FALSE, randomStarts=0, ...)
cfT(A, Tmat=diag(ncol(A)), kappa=0, normalize=FALSE, randomStarts=0, ...)
cfQ(A, Tmat=diag(ncol(A)), kappa=0, normalize=FALSE, randomStarts=0, ...)
equamax(A, Tmat=diag(ncol(A)), kappa=ncol(A)/(2*nrow(A)), normalize=FALSE,
randomStarts=0, ...)
parsimax(A, Tmat=diag(ncol(A)), kappa=(ncol(A)-1)/(ncol(A)+nrow(A)-2),
normalize=FALSE, randomStarts=0, ...)
infomaxT(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
infomaxQ(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
mccammon(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
varimin(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
bifactorT(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
bifactorQ(A, Tmat=diag(ncol(A)), normalize=FALSE, randomStarts=0, ...)
lpT(A, Tmat=diag(ncol(A)), p=1, normalize=FALSE, eps=1e-05, maxit=1000,
randomStarts=0, gpaiter=5)
lpQ(A, Tmat=diag(ncol(A)), p=1, normalize=FALSE, eps=1e-05, maxit=1000,
randomStarts=0, gpaiter=5)Arguments
- A
an initial loadings matrix to be rotated.
- Tmat
initial rotation matrix.
- gam
Obliqueness parameter (\(\gamma\) in the mathematical definition). 0=Quartimin, .5=Biquartimin, 1=Covarimin.
- Target
rotation target for objective calculation.
- W
weighting of each element in target.
- k
number of close to zero loadings.
- delta
constant added to \(\Lambda^2\) in the objective calculation.
- kappa
see details.
- normalize
parameter passed to optimization routine (GPForth or GPFoblq).
- eps
convergence tolerance passed to
GPForthorGPFoblqvia.... Convergence is assumed when the norm of the gradient is smaller thaneps. Default is1e-5.- maxit
maximum number of iterations passed to
GPForthorGPFoblqvia.... Default is1000.- ...
additional arguments passed to
GPForthorGPFoblq, includingepsandmaxit.- randomStarts
parameter passed to optimization routine (GPFRSorth or GPFRSoblq).
- L
provided for backward compatibility in target rotations only. Use A going forward.
- p
Component-wise \(L^p\), where 0 < p \(=<\) 1.
- gpaiter
Maximum iterations for GPA rotation loop in \(L^p\) rotation.
Value
A GPArotation object which is a list with elements:
- loadings
The rotated loadings matrix, one column per factor. If random starts were requested, this is the solution with the lowest criterion value.
- Th
The rotation matrix, satisfying
loadings %*% t(Th) = Afor orthogonal rotation andloadings = A %*% solve(t(Th))for oblique rotation.- Table
A matrix recording the iteration history: iteration number, criterion value, log10 of the gradient norm, and step size (alpha).
- method
A string indicating the rotation criterion.
- 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. Omitted (NULL) for orthogonal rotations.- Gq
The gradient of the criterion at the rotated loadings.
- randStartChar
A named vector summarising random start results:
randomStarts,Converged,atMinimum,localMins. Only present whenrandomStarts > 1.
Details
These functions optimize a rotation objective. They can be used directly or the
function name can be passed to factor analysis functions like factanal.
Several of the function names end in T or Q, which indicates if they are
orthogonal or oblique rotations (using GPFRSorth or GPFRSoblq
respectively). The gradient projection algorithms are described in
Bernaards and Jennrich (2005).
oblimin | oblique | oblimin family; gam controls obliqueness |
quartimin | oblique | oblimin with gam = 0 |
targetT | orthogonal | rotation towards a target matrix |
targetQ | oblique | rotation towards a target matrix |
pstT | orthogonal | partially specified target rotation |
pstQ | oblique | partially specified target rotation |
oblimax | oblique | maximizes overall kurtosis of loadings |
entropy | orthogonal | minimizes entropy of squared loadings |
quartimax | orthogonal | maximizes variance of squared loadings within variables |
Varimax | orthogonal | maximizes variance of squared loadings within factors |
simplimax | oblique | minimizes the k smallest squared loadings |
bentlerT | orthogonal | invariant pattern simplicity |
bentlerQ | oblique | invariant pattern simplicity |
tandemI | orthogonal | factors share high loadings on same variables |
tandemII | orthogonal | factors do not share high loadings on same variables |
geominT | orthogonal | minimizes geometric mean of squared loadings |
geominQ | oblique | minimizes geometric mean of squared loadings |
bigeominT | orthogonal | geomin with a general factor in column 1 |
bigeominQ | oblique | geomin with a general factor in column 1 |
cfT | orthogonal | Crawford-Ferguson family; kappa controls complexity |
cfQ | oblique | Crawford-Ferguson family; kappa controls complexity |
equamax | orthogonal | Crawford-Ferguson with kappa = m/(2p) |
parsimax | orthogonal | Crawford-Ferguson with kappa = (m-1)/(p+m-2) |
infomaxT | orthogonal | infomax information criterion |
infomaxQ | oblique | infomax information criterion |
mccammon | orthogonal | minimizes entropy ratio across factors |
varimin | orthogonal | minimizes variance of squared loadings within factors |
bifactorT | orthogonal | bifactor; general factor in column 1 |
bifactorQ | oblique | biquartimin; general factor in column 1 |
lpT | orthogonal | \(L^p\) sparsity rotation |
lpQ | oblique | \(L^p\) sparsity rotation |
The Varimax implementation in the list uses the gradient projection algorithm
applied to vgQ.varimax. This implementation is different that the
varimax rotation defined in the stats package. Additionally,
varimax does Kaiser normalization by default whereas
GPArotation::Varimax does not.
The argument kappa parameterizes the family for the Crawford-Ferguson
method. If m is the number of factors and p is the number of
indicators then kappa values having special names are \(0=\)Quartimax,
\(1/p=\)Varimax, \(m/(2*p)=\)Equamax,
\((m-1)/(p+m-2)=\)Parsimax, \(1=\)Factor parsimony.
Bifactor rotations, bifactorT and bifactorQ are called bifactor and biquartimin in Jennrich and Bentler (2011). For a comparison of exploratory bifactor analysis algorithms including those implemented here, see Garcia-Garzon, Abad and Garrido (2021).
The argument p is needed for \(L^p\) rotation. See
Lp rotation for details on the rotation method.
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. doi: 10.1177/0013164404272507
Bi, Y. and Barchard, K.A. (2024). Purchasing choices that reduce climate change: An exploratory factor analysis. Spectra Undergraduate Research Journal, 3(2), 8–14. doi: 10.9741/2766-7227.1028.
Fischer, R., & Fontaine, J. (2010). Methods for investigating structural equivalence. In D. Matsumoto & F. van de Vijver (Eds.), Cross-Cultural Research Methods in Psychology (pp. 179–215). Cambridge University Press. doi: 10.1017/CBO9780511779381.010
Garcia-Garzon, E., Abad, F.J. and Garrido, L.E. (2021). On omega hierarchical estimation: A comparison of exploratory bi-factor analysis algorithms. Multivariate Behavioral Research, 56(1), 101–119. doi: 10.1080/00273171.2020.1736977
Jennrich, R.I. and Bentler, P.M. (2011). Exploratory bi-factor analysis. Psychometrika, 76(4), 537–549. doi: 10.1007/s11336-011-9218-4
For references to individual rotation criteria see
vignette("GPA1guide", package = "GPArotation").
Examples
# For extended examples see the vignettes:
# vignette("GPA1guide", package = "GPArotation")
# vignette("GPA2local", package = "GPArotation")
# vignette("GPA3bifactor", package = "GPArotation")
# --- Accessing rotated loadings ---
data("Harman", package = "GPArotation") # 8 physical variables
qHarman <- quartimax(Harman8)
loadings(qHarman) # via extractor (recommended)
#> CF1 CF2
#> height 0.8987554 0.1948197
#> arm.span 0.9339440 0.1297446
#> forearm 0.9021319 0.1038604
#> lower.leg 0.8765090 0.1712805
#> weight 0.3155758 0.8764747
#> bitro.diameter 0.2511265 0.7734879
#> chest.girth 0.1980102 0.7146775
#> chest.width 0.3078601 0.6593331
qHarman$loadings # via direct list access
#> CF1 CF2
#> height 0.8987554 0.1948197
#> arm.span 0.9339440 0.1297446
#> forearm 0.9021319 0.1038604
#> lower.leg 0.8765090 0.1712805
#> weight 0.3155758 0.8764747
#> bitro.diameter 0.2511265 0.7734879
#> chest.girth 0.1980102 0.7146775
#> chest.width 0.3078601 0.6593331
all.equal(loadings(qHarman), qHarman$loadings) # identical
#> [1] TRUE
# --- Rotating factanal loadings ---
data("WansbeekMeijer", package = "GPArotation") # Netherlands TV viewership
fa.unrotated <- factanal(factors = 2, covmat = NetherlandsTV,
normalize = TRUE, rotation = "none")
quartimax(loadings(fa.unrotated), normalize = TRUE)
#> Orthogonal rotation method Quartimax converged.
#> Loadings:
#> Factor1 Factor2
#> NL1 0.327 0.720
#> TV2 0.424 0.725
#> NL3 0.323 0.703
#> RTL4 0.669 0.214
#> RTL5 0.738 0.183
#> Veronica 0.811 0.109
#> SBS6 0.719 0.106
#>
#> Factor1 Factor2
#> SS loadings 2.556 1.641
#> Proportion Var 0.365 0.234
#> Cumulative Var 0.365 0.600
geominQ(loadings(fa.unrotated), normalize = TRUE, randomStarts = 100)
#> Oblique rotation method Geomin converged at lowest minimum.
#> Of 100 random starts 100% converged, 100% at the same lowest minimum.
#> Loadings at lowest minimum:
#> Factor1 Factor2
#> NL1 -0.016 0.800
#> TV2 0.090 0.785
#> NL3 -0.011 0.780
#> RTL4 0.631 0.113
#> RTL5 0.724 0.060
#> Veronica 0.844 -0.046
#> SBS6 0.743 -0.029
#>
#> Factor1 Factor2
#> SS loadings 2.254 1.943
#> Proportion Var 0.322 0.278
#> Cumulative Var 0.322 0.600
#>
#> Phi:
#> Factor1 Factor2
#> Factor1 1.000 0.582
#> Factor2 0.582 1.000
# --- Passing rotation to factanal ---
# CCAI:Climate-Friendly Purchasing Choices domain of the Climate Change Action Inventory
data("CCAI", package = "GPArotation")
factanal(factors = 3, covmat = CCAI_R, n.obs = 461, rotation = "infomaxT")
#>
#> Call:
#> factanal(factors = 3, covmat = CCAI_R, n.obs = 461, rotation = "infomaxT")
#>
#> Uniquenesses:
#> CCAI8 CCAI6 CCAI7 CCAI11 CCAI12 CCAI10 CCAI14 CCAI13 CCAI5 CCAI2 CCAI4
#> 0.128 0.272 0.299 0.247 0.266 0.347 0.055 0.077 0.286 0.612 0.321
#> CCAI1 CCAI3 CCAI9
#> 0.455 0.364 0.372
#>
#> Loadings:
#> Factor1 Factor2 Factor3
#> CCAI8 0.864 0.277 0.222
#> CCAI6 0.774 0.289 0.214
#> CCAI7 0.744 0.343 0.172
#> CCAI11 0.634 0.434 0.404
#> CCAI12 0.600 0.397 0.465
#> CCAI10 0.520 0.463 0.410
#> CCAI14 0.302 0.277 0.882
#> CCAI13 0.318 0.313 0.851
#> CCAI5 0.308 0.460 0.638
#> CCAI2 0.237 0.567 0.102
#> CCAI4 0.273 0.739 0.241
#> CCAI1 0.278 0.656 0.193
#> CCAI3 0.355 0.653 0.290
#> CCAI9 0.409 0.589 0.337
#>
#> Factor1 Factor2 Factor3
#> SS loadings 3.720 3.296 2.884
#> Proportion Var 0.266 0.235 0.206
#> Cumulative Var 0.266 0.501 0.707
#>
#> Test of the hypothesis that 3 factors are sufficient.
#> The chi square statistic is 387.64 on 52 degrees of freedom.
#> The p-value is 7.58e-53
factanal(factors = 3, covmat = CCAI_R, n.obs = 461, rotation = "infomaxT",
control = list(rotate = list(normalize = TRUE, eps = 1e-6)))
#>
#> Call:
#> factanal(factors = 3, covmat = CCAI_R, n.obs = 461, rotation = "infomaxT", control = list(rotate = list(normalize = TRUE, eps = 1e-06)))
#>
#> Uniquenesses:
#> CCAI8 CCAI6 CCAI7 CCAI11 CCAI12 CCAI10 CCAI14 CCAI13 CCAI5 CCAI2 CCAI4
#> 0.128 0.272 0.299 0.247 0.266 0.347 0.055 0.077 0.286 0.612 0.321
#> CCAI1 CCAI3 CCAI9
#> 0.455 0.364 0.372
#>
#> Loadings:
#> Factor1 Factor2 Factor3
#> CCAI8 0.322 0.852 0.205
#> CCAI6 0.329 0.762 0.198
#> CCAI7 0.381 0.729 0.155
#> CCAI11 0.473 0.617 0.386
#> CCAI12 0.436 0.586 0.448
#> CCAI10 0.496 0.502 0.392
#> CCAI14 0.312 0.298 0.871
#> CCAI13 0.348 0.312 0.840
#> CCAI5 0.489 0.293 0.623
#> CCAI2 0.580 0.211
#> CCAI4 0.756 0.241 0.220
#> CCAI1 0.673 0.249 0.174
#> CCAI3 0.676 0.327 0.270
#> CCAI9 0.615 0.385 0.318
#>
#> Factor1 Factor2 Factor3
#> SS loadings 3.671 3.507 2.721
#> Proportion Var 0.262 0.251 0.194
#> Cumulative Var 0.262 0.513 0.707
#>
#> Test of the hypothesis that 3 factors are sufficient.
#> The chi square statistic is 387.64 on 52 degrees of freedom.
#> The p-value is 7.58e-53
# --- Target rotation ---
# Orthogonal target rotation of two varimax rotated matrices
# towards each other. Data from Fischer and Fontaine (2010).
# See vignette("GPA1guide", package = "GPArotation") for further analyses.
trBritain <- matrix(c(.783, -.163, .811, .202, .724, .209, .850, .064,
-.031, .592, -.028, .723, .388, .434, .141, .808,
.215, .709), byrow = TRUE, ncol = 2)
trGermany <- matrix(c(.778, -.066, .875, .081, .751, .079, .739, .092,
.195, .574, -.030, .807, -.135, .717, .125, .738,
.060, .691), byrow = TRUE, ncol = 2)
trx <- targetT(trGermany, Target = trBritain)
round(trx$loadings - trBritain, 3) # difference from target
#> [,1] [,2]
#> [1,] -0.009 0.064
#> [2,] 0.067 -0.159
#> [3,] 0.030 -0.162
#> [4,] -0.108 -0.004
#> [5,] 0.250 -0.027
#> [6,] 0.033 0.085
#> [7,] -0.492 0.288
#> [8,] 0.015 -0.076
#> [9,] -0.125 -0.021
# --- Partially specified target rotation ---
# See vignette("GPA1guide", package = "GPArotation") for full context.
# Unrotated loadings matrix A and partially specified target SPA
# NA entries in SPA are unspecified --- rotation is free there
# Numeric entries are the target values the rotation aims towards
A <- matrix(c(.664, .688, .492, .837, .705, .82, .661, .457, .765, .322,
.248, .304, -0.291, -0.314, -0.377, .397, .294, .428,
-0.075, .192, .224, .037, .155, -.104, .077, -.488, .009), ncol = 3)
SPA <- matrix(c(rep(NA, 6), .7, .0, .7, rep(0, 3), rep(NA, 7),
0, 0, NA, 0, rep(NA, 4)), ncol = 3)
comparison <- cbind(round(A, 3), rep(NA, nrow(A)), SPA)
colnames(comparison) <- c("A.F1", "A.F2", "A.F3", "|", "T.F1", "T.F2", "T.F3")
cat("Unrotated loadings (A) and partially specified target (SPA):\n")
#> Unrotated loadings (A) and partially specified target (SPA):
print(comparison, na.print = "NA")
#> A.F1 A.F2 A.F3 | T.F1 T.F2 T.F3
#> [1,] 0.664 0.322 -0.075 NA NA 0 NA
#> [2,] 0.688 0.248 0.192 NA NA 0 0
#> [3,] 0.492 0.304 0.224 NA NA 0 0
#> [4,] 0.837 -0.291 0.037 NA NA NA NA
#> [5,] 0.705 -0.314 0.155 NA NA NA 0
#> [6,] 0.820 -0.377 -0.104 NA NA NA NA
#> [7,] 0.661 0.397 0.077 NA 0.7 NA NA
#> [8,] 0.457 0.294 -0.488 NA 0.0 NA NA
#> [9,] 0.765 0.428 0.009 NA 0.7 NA NA
targetT(A, Target = SPA)
#> Orthogonal rotation method Target rotation converged.
#> Loadings:
#> [,1] [,2] [,3]
#> [1,] 0.611 0.023 0.420
#> [2,] 0.734 0.055 0.173
#> [3,] 0.607 -0.086 0.093
#> [4,] 0.608 0.622 0.176
#> [5,] 0.549 0.564 0.017
#> [6,] 0.499 0.713 0.261
#> [7,] 0.705 -0.069 0.314
#> [8,] 0.235 0.023 0.691
#> [9,] 0.768 -0.039 0.422
#>
#> [,1] [,2] [,3]
#> SS loadings 3.341 1.231 1.068
#> Proportion Var 0.371 0.137 0.119
#> Cumulative Var 0.371 0.508 0.627
# --- Random starts ---
# CCAI Climate-Friendly Purchasing Choices domain, 14 items, 3 oblique factors.
# High factor intercorrelations make oblimin the natural choice.
# Note: factanal uses MLE extraction; results differ somewhat from
# PCA-based extraction used in Bi and Barchard (2024).
data("CCAI", package = "GPArotation")
fa.unrotated <- factanal(factors = 3, covmat = CCAI_R, n.obs = 461, rotation = "none")
oblimin(loadings(fa.unrotated), Tmat = Random.Start(3)) # single random start
#> Oblique rotation method Oblimin Quartimin converged.
#> Loadings:
#> Factor1 Factor2 Factor3
#> CCAI8 0.984 -0.064 -0.011
#> CCAI6 0.858 -0.005 -0.002
#> CCAI7 0.806 0.100 -0.068
#> CCAI11 0.537 0.198 0.237
#> CCAI12 0.489 0.138 0.338
#> CCAI10 0.366 0.287 0.263
#> CCAI14 0.001 -0.048 1.001
#> CCAI13 0.016 0.007 0.946
#> CCAI5 0.003 0.296 0.619
#> CCAI2 0.028 0.668 -0.107
#> CCAI4 -0.046 0.848 0.013
#> CCAI1 0.014 0.745 -0.025
#> CCAI3 0.090 0.672 0.085
#> CCAI9 0.179 0.541 0.154
#>
#> Factor1 Factor2 Factor3
#> SS loadings 3.601 3.260 3.039
#> Proportion Var 0.257 0.233 0.217
#> Cumulative Var 0.257 0.490 0.707
#>
#> Phi:
#> Factor1 Factor2 Factor3
#> Factor1 1.000 0.707 0.622
#> Factor2 0.707 1.000 0.652
#> Factor3 0.622 0.652 1.000
oblimin(loadings(fa.unrotated), randomStarts = 1) # equivalent
#> Oblique rotation method Oblimin Quartimin converged.
#> Loadings:
#> Factor1 Factor2 Factor3
#> CCAI8 0.984 -0.064 -0.011
#> CCAI6 0.858 -0.005 -0.002
#> CCAI7 0.806 0.100 -0.068
#> CCAI11 0.537 0.198 0.237
#> CCAI12 0.489 0.138 0.338
#> CCAI10 0.366 0.287 0.263
#> CCAI14 0.001 -0.048 1.001
#> CCAI13 0.016 0.007 0.946
#> CCAI5 0.003 0.296 0.619
#> CCAI2 0.028 0.668 -0.107
#> CCAI4 -0.046 0.848 0.013
#> CCAI1 0.014 0.745 -0.025
#> CCAI3 0.090 0.672 0.085
#> CCAI9 0.179 0.541 0.154
#>
#> Factor1 Factor2 Factor3
#> SS loadings 3.601 3.260 3.039
#> Proportion Var 0.257 0.233 0.217
#> Cumulative Var 0.257 0.490 0.707
#>
#> Phi:
#> Factor1 Factor2 Factor3
#> Factor1 1.000 0.707 0.622
#> Factor2 0.707 1.000 0.652
#> Factor3 0.622 0.652 1.000
oblimin(loadings(fa.unrotated), randomStarts = 100) # multiple starts
#> Oblique rotation method Oblimin Quartimin converged at lowest minimum.
#> Of 100 random starts 100% converged, 100% at the same lowest minimum.
#> Loadings at lowest minimum:
#> Factor1 Factor2 Factor3
#> CCAI8 0.984 -0.064 -0.011
#> CCAI6 0.858 -0.005 -0.002
#> CCAI7 0.806 0.100 -0.068
#> CCAI11 0.537 0.198 0.237
#> CCAI12 0.489 0.138 0.338
#> CCAI10 0.366 0.287 0.263
#> CCAI14 0.001 -0.048 1.001
#> CCAI13 0.016 0.007 0.946
#> CCAI5 0.003 0.296 0.619
#> CCAI2 0.028 0.668 -0.107
#> CCAI4 -0.046 0.847 0.013
#> CCAI1 0.014 0.745 -0.025
#> CCAI3 0.090 0.672 0.085
#> CCAI9 0.179 0.541 0.154
#>
#> Factor1 Factor2 Factor3
#> SS loadings 3.601 3.260 3.039
#> Proportion Var 0.257 0.233 0.217
#> Cumulative Var 0.257 0.490 0.707
#>
#> Phi:
#> Factor1 Factor2 Factor3
#> Factor1 1.000 0.707 0.622
#> Factor2 0.707 1.000 0.652
#> Factor3 0.622 0.652 1.000
# Directly via factanal call
factanal(factors = 3, covmat = CCAI_R, n.obs = 461, rotation = "oblimin",
control = list(rotate = list(normalize = TRUE, gam = -0.1, randomStarts = 100)))
#>
#> Call:
#> factanal(factors = 3, covmat = CCAI_R, n.obs = 461, rotation = "oblimin", control = list(rotate = list(normalize = TRUE, gam = -0.1, randomStarts = 100)))
#>
#> Uniquenesses:
#> CCAI8 CCAI6 CCAI7 CCAI11 CCAI12 CCAI10 CCAI14 CCAI13 CCAI5 CCAI2 CCAI4
#> 0.128 0.272 0.299 0.247 0.266 0.347 0.055 0.077 0.286 0.612 0.321
#> CCAI1 CCAI3 CCAI9
#> 0.455 0.364 0.372
#>
#> Loadings:
#> Factor1 Factor2 Factor3
#> CCAI8 0.962
#> CCAI6 0.840
#> CCAI7 0.788 0.109
#> CCAI11 0.535 0.200 0.252
#> CCAI12 0.490 0.143 0.347
#> CCAI10 0.370 0.283 0.280
#> CCAI14 0.977
#> CCAI13 0.926
#> CCAI5 0.288 0.622
#> CCAI2 0.639
#> CCAI4 0.810
#> CCAI1 0.712
#> CCAI3 0.645 0.121
#> CCAI9 0.187 0.522 0.183
#>
#> Factor1 Factor2 Factor3
#> SS loadings 3.61 3.159 3.13
#>
#> Factor Correlations:
#> Factor1 Factor2 Factor3
#> Factor1 1.000 0.678 0.587
#> Factor2 0.678 1.000 0.602
#> Factor3 0.587 0.602 1.000
#>
#> Test of the hypothesis that 3 factors are sufficient.
#> The chi square statistic is 387.64 on 52 degrees of freedom.
#> The p-value is 7.58e-53
# --- Assessing local minima ---
# For detailed investigation of local minima across all random starts
# see vignette("GPA2local", package = "GPArotation").
data(Thurstone, package = "GPArotation")
infomaxQ(box26, normalize = TRUE, randomStarts = 150)
#> Oblique rotation method Infomax converged at lowest minimum.
#> Of 150 random starts 100% converged, 31% at the same lowest minimum.
#> Random starts converged to 9 different local minima.
#> Loadings at lowest minimum:
#> [,1] [,2] [,3]
#> [1,] -0.698 0.733 0.741
#> [2,] 0.632 -0.446 0.679
#> [3,] 0.734 0.665 -0.489
#> [4,] -0.012 0.102 0.937
#> [5,] 0.055 0.906 0.094
#> [6,] 0.894 0.107 0.057
#> [7,] -0.308 0.407 0.892
#> [8,] 0.310 -0.145 0.841
#> [9,] -0.254 0.895 0.348
#> [10,] 0.329 0.934 -0.119
#> [11,] 0.856 -0.113 0.274
#> [12,] 0.881 0.301 -0.143
#> [13,] -1.068 1.019 -0.025
#> [14,] 1.068 -1.019 0.025
#> [15,] -1.147 0.000 1.072
#> [16,] 1.147 0.000 -1.072
#> [17,] 0.008 -1.057 1.028
#> [18,] -0.008 1.057 -1.028
#> [19,] 0.090 -0.006 0.922
#> [20,] 0.096 0.922 0.023
#> [21,] 0.876 0.109 0.082
#> [22,] 0.100 0.001 0.900
#> [23,] 0.122 0.886 0.013
#> [24,] 0.837 0.102 0.116
#> [25,] 0.348 0.405 0.419
#> [26,] 0.473 0.310 0.358
#>
#> [,1] [,2] [,3]
#> SS loadings 8.668 8.559 8.183
#> Proportion Var 0.333 0.329 0.315
#> Cumulative Var 0.333 0.663 0.977
#>
#> Phi:
#> [,1] [,2] [,3]
#> [1,] 1.000 0.548 0.607
#> [2,] 0.548 1.000 0.543
#> [3,] 0.607 0.543 1.000
geominQ(box26, normalize = TRUE, randomStarts = 150)
#> Oblique rotation method Geomin converged at lowest minimum.
#> Of 150 random starts 100% converged, 23% at the same lowest minimum.
#> Random starts converged to 4 different local minima.
#> Loadings at lowest minimum:
#> [,1] [,2] [,3]
#> [1,] -0.015 -0.010 0.993
#> [2,] 0.942 0.048 0.059
#> [3,] 0.061 0.965 -0.001
#> [4,] 0.642 -0.014 0.637
#> [5,] 0.002 0.646 0.596
#> [6,] 0.613 0.644 -0.025
#> [7,] 0.383 0.007 0.835
#> [8,] 0.812 0.034 0.385
#> [9,] -0.020 0.418 0.788
#> [10,] 0.027 0.858 0.444
#> [11,] 0.766 0.452 -0.019
#> [12,] 0.442 0.784 -0.029
#> [13,] -0.829 0.009 0.747
#> [14,] 0.829 -0.009 -0.747
#> [15,] 0.006 -0.825 0.816
#> [16,] -0.006 0.825 -0.816
#> [17,] 0.848 -0.798 -0.009
#> [18,] -0.848 0.798 0.009
#> [19,] 0.710 -0.020 0.548
#> [20,] -0.023 0.689 0.557
#> [21,] 0.618 0.631 -0.006
#> [22,] 0.700 -0.008 0.537
#> [23,] -0.009 0.681 0.525
#> [24,] 0.618 0.599 0.016
#> [25,] 0.478 0.466 0.453
#> [26,] 0.528 0.487 0.340
#>
#> [,1] [,2] [,3]
#> SS loadings 8.824 8.795 7.790
#> Proportion Var 0.339 0.338 0.300
#> Cumulative Var 0.339 0.678 0.977
#>
#> Phi:
#> [,1] [,2] [,3]
#> [1,] 1.000 0.268 0.206
#> [2,] 0.268 1.000 0.278
#> [3,] 0.206 0.278 1.000