I recently noticed that psych::principal
reorders principal components on (automatic) rotation, according to their Eigenvalues (from highest to lowest).
(Recall that rotation matrix-multiplies the loadings, and so the order of their squared column sums (fka. the Eigenvalues) can change, too).
Here's an example:
library(qmethod)
library(psych)
data("lipset") # this dataset is used because it causes a re-ordering of components
Lipset <- cor(x = lipset[[1]], method = "pearson") # must calculate cor matrix first
# calculate unrotated loadings:
principal.unrotated <- principal(r = Lipset, nfactors = 4, rotate = "none")$loa
# calculate varimax rotated loadings:
principal.varimax <- principal(r = Lipset, nfactors = 4, rotate = "varimax")$loa
# manually calculate varimax rotmat on unrotated loadings:
rot.mat.varimax <- varimax(x = principal.unrotated)$rotmat
# should manually reproduce the varimax rotation:
repr.varimax <- unclass(principal.unrotated) %*% rot.mat.varimax
repr.varimax
#> [,1] [,2] [,3] [,4]
#> US1 -0.229427530 0.15096123 0.81283285 0.06465534
#> US2 0.002334831 -0.11383236 0.89114173 -0.06389700
#> US3 -0.009194167 0.79325633 0.03603989 0.18951141
#> US4 0.255174168 0.76681887 0.26319367 -0.08631099
#> JP5 0.003227787 -0.87396713 0.21605277 0.05615580
#> CA6 0.922371369 0.08409883 -0.01191349 -0.08215986
#> UK7 0.823285358 0.07913797 -0.17255592 0.03003107
#> US8 -0.447664930 0.02677531 0.37686206 -0.60826777
#> FR9 -0.158333934 0.06509079 0.11083125 0.87837316
# notice how eigenvalue order is out of whack:
apply(X = repr.varimax, MARGIN = 2, FUN = function(x) sum(x^2))
#> [1] 1.871892 2.035122 1.756305 1.203962
unclass(principal.varimax) # notice how cols 1 and 2 have changed
#> PC2 PC1 PC3 PC4
#> US1 0.15096123 -0.229427530 0.81283285 0.06465534
#> US2 -0.11383236 0.002334831 0.89114173 -0.06389700
#> US3 0.79325633 -0.009194167 0.03603989 0.18951141
#> US4 0.76681887 0.255174168 0.26319367 -0.08631099
#> JP5 -0.87396713 0.003227787 0.21605277 0.05615580
#> CA6 0.08409883 0.922371369 -0.01191349 -0.08215986
#> UK7 0.07913797 0.823285358 -0.17255592 0.03003107
#> US8 0.02677531 -0.447664930 0.37686206 -0.60826777
#> FR9 0.06509079 -0.158333934 0.11083125 0.87837316
# eigenvalue order is fine again:
apply(X = principal.varimax, MARGIN = 2, FUN = function(x) sum(x^2))
#> PC2 PC1 PC3 PC4
#> 2.035122 1.871892 1.756305 1.203962
I get how and why this works.
My question is simply: is there a reason – other than convention or convenience – why this reordering would be necessary?
(This causes a bunch of problems for my use case in another function, and I'd like to avoid if that is statistically sound).
The way I see it, rotated principal components are no longer principal components anyway, so you might as well leave them in any order they come in.
Best Answer
As the author of the psych package I will try to explain what is going on and offer a solution.
First, as @ttnhpns correctly points out, rotated principal components are no longer principal components, they are merely components. @ttnhpns is also correct that we should not call the sums of squares of these rotated components "eigen values" but rather "after rotation Sums of squares". (Indeed, that is how they are labeled in the output.) However, common usage, unfortunately, tends to call them eigen values.
Then, when rotating a solution, the order of the sums of squares of the rotated components will not necessarily be monotonically decreasing. A conventional solution to this problem is to order by Sums of Squares and then just name the components RC1 ... RCn and forget about it. I prefer to keep the names of the unrotated components to highlight what rotation does. (Which is to change the amount of importance of each component.)
This has been asked a lot and in fact has led to the final comment on the
fa
help page (and probably should be added theprincipal
help page as well):To make the order of the rotated / transformed components match that of the unrotated, you can just reorder the components using the
fa.organize
function.If enough people request it, the next psych release (which won't be for several months) can include a do not reorder option, but I prefer the
fa.reorganize
option.