set.seed (2026)
# 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)
qHarman$loadings # via direct list access
all.equal(loadings(qHarman), qHarman$loadings) # identical
# --- Rotating factanal loadings ---
data("WansbeekMeijer", package = "GPArotation") # Netherlands TV viewership
fa.unrotated <- factanal(factors = 2, covmat = NetherlandsTV,
normalize = TRUE, rotation = "none")
quartimax(fa.unrotated, normalize = TRUE)
geominQ(fa.unrotated, normalize = TRUE, randomStarts = 100)
# --- 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")
factanal(factors = 3, covmat = CCAI_R, n.obs = 461, rotation = "infomaxT",
control = list(rotate = list(normalize = TRUE, eps = 1e-6)))
# --- 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)
print(trx$loadings - trBritain, cutoff = 0, digits = 3) # difference from target
# Plot discrepancy from target --- steelblue = below target, firebrick = above
plot(trx, type = "target", Target = trBritain)
# \donttest{
# --- Promax via targetQ, vs. stats::promax ---
# targetQ enforces the oblique normalization throughout the fit,
# rather than correcting for it afterward as stats::promax does;
# this reaches a lower value of the fitting criterion on the
# identical target.
data("Harman", package = "GPArotation")
xv <- unclass(loadings(Varimax(Harman8)))
target <- xv * abs(xv)^(4 - 1)
res.pq <- targetQ(Harman8, Target = target)
res.pm <- promax(Harman8)
sum((unclass(res.pq$loadings) - target)^2) # targetQ
sum((unclass(res.pm$loadings) - target)^2) # stats::promax
# --- 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")
print(comparison, na.print = "NA")
res.t <- targetT(A, Target = SPA)
print(res.t)
# Discrepancy from target --- specified elements only
plot(res.t, type = "target", Target = SPA)
# --- Random starts and Update calls ---
# 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")
# Single random start via Tmat
res.o <- oblimin(fa.unrotated, Tmat = Random.Start(3))
res.o <- oblimin(fa.unrotated, randomStarts = 1) # equivalent using randomStarts = 1
res.o <- oblimin(fa.unrotated, randomStarts = 100) # multiple random starts
# Update arguments without re-specifying the full call
res.o2 <- update(res.o, randomStarts = 250) # randomStarts = 250
res.o3 <- update(res.o, gam = -0.5) # gam = -0.5, randomStarts = 100
res.o4 <- update(res.o, normalize = TRUE) # normalize = TRUE, randomStarts = 100
# To change rotation criterion, use A_unrotated directly
A <- attr(res.o, "A_unrotated")
res.qt <- GPFRSoblq(A, method = "quartimin")
# 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 = 10)))
# --- 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)
geominQ(box26, normalize = TRUE, randomStarts = 150)
# }
Run the code above in your browser using DataLab