data(CCAI, package = "GPArotation")
# Observed correlation matrix
round(CCAI_R, 2)
# Published pattern matrix and factor intercorrelations
round(CCAI_pattern, 2)
round(CCAI_Phi, 2)
# Reproduce published analysis: PCA extraction via eigendecomposition
# followed by oblimin rotation. No additional packages required.
# Gives the same result as psych::principal used by Bi and Barchard (2024).
ev <- eigen(CCAI_R)
k <- 3
L_unrotated <- ev$vectors[, 1:k] %*% diag(sqrt(ev$values[1:k]))
rownames(L_unrotated) <- colnames(CCAI_R)
res.ob <- oblimin(L_unrotated, randomStarts = 100)
# Sort and extract loadings for comparison
res_sorted <- GPArotation:::.sortGPALoadings(res.ob)
L_repro <- unclass(res_sorted$loadings)
# Compare reproduced vs published side by side, alternating by factor
comparison <- cbind(round(L_repro[, 1], 2), round(CCAI_pattern[, 1], 2),
round(L_repro[, 2], 2), round(CCAI_pattern[, 2], 2),
round(L_repro[, 3], 2), round(CCAI_pattern[, 3], 2))
colnames(comparison) <- c("F1.repro", "F1.pub",
"F2.repro", "F2.pub",
"F3.repro", "F3.pub")
print(comparison)
# --- Tandem criteria ---
# Stage 1: TandemI reveals factor redundancy structure.
# One dominant general factor (SS = 8.3, 59% variance) suggests
# highly correlated underlying constructs.
res.t1 <- tandemI(L_unrotated, randomStarts = 100)
print(res.t1)
# Stage 2: TandemII for simple structure (orthogonal constraint).
res.t2 <- tandemII(L_unrotated, randomStarts = 100)
summary(res.t2)
# For heavily correlated constructs, oblique rotation achieves
# substantially cleaner simple structure than TandemII.
# Compare AUC and hyperplane counts across methods.
cat(" AUC Hyperplane\n")
cat("TandemII ",
round(GPArotation:::calc_AUC(res.t2)$AUC_mean, 3), " ",
sum(abs(unclass(res.t2$loadings)) < 0.1), "loadings\n")
cat("Oblimin ",
round(GPArotation:::calc_AUC(res.ob)$AUC_mean, 3), " ",
sum(abs(unclass(res.ob$loadings)) < 0.1), "loadings\n")
# Orthogonal bifactor rotation using MLE extraction
fa.un <- factanal(factors = 3, covmat = CCAI_R, n.obs = 461,
rotation = "none")
bif <- bifactorT(fa.un)
print(bif, sortLoadings = FALSE, digits = 3, cutoff = 0.05)
Run the code above in your browser using DataLab