Compute Classical Principal Components via SVD or Eigen
classPC(x, scale = FALSE, center = TRUE, signflip = TRUE, via.svd = n > p, scores = FALSE)
x |
a numeric |
scale |
logical indicating if the matrix should be scaled; it is
mean centered in any case (via
|
center |
logical or numeric vector for “centering” the matrix. |
signflip |
logical indicating if the sign(.) of the loadings should be determined should flipped such that the absolutely largest value is always positive. |
via.svd |
logical indicating if the computation is via SVD or Eigen decomposition; the latter makes sense typically only for n <= p. |
scores |
logical indicating |
a list
with components
rank |
the (numerical) matrix rank of |
eigenvalues |
the k eigenvalues, in the n > p case, proportional to the variances. |
loadings |
the loadings, a p * k matrix. |
scores |
if the |
center |
a numeric p-vector of means, unless the
|
scale |
if the |
Valentin Todorov; efficiency tweaks by Martin Maechler
set.seed(17) x <- matrix(rnorm(120), 10, 12) # n < p {the unusual case} pcx <- classPC(x) (k <- pcx$rank) # = 9 [after centering!] pc2 <- classPC(x, scores=TRUE) pcS <- classPC(x, via.svd=TRUE) all.equal(pcx, pcS, tol = 1e-8) ## TRUE: eigen() & svd() based PC are close here pc0 <- classPC(x, center=FALSE, scale=TRUE) pc0$rank # = 10 here *no* centering (as E[.] = 0) ## Loadings are orthnormal: zapsmall( crossprod( pcx$loadings ) ) ## PC Scores are roughly orthogonal: S.S <- crossprod(pc2$scores) print.table(signif(zapsmall(S.S), 3), zero.print=".") stopifnot(all.equal(pcx$eigenvalues, diag(S.S)/k)) ## the usual n > p case : pc.x <- classPC(t(x)) pc.x$rank # = 10, full rank in the n > p case cpc1 <- classPC(cbind(1:3)) # 1-D matrix stopifnot(cpc1$rank == 1, all.equal(cpc1$eigenvalues, 1), all.equal(cpc1$loadings, 1))
Please choose more modern alternatives, such as Google Chrome or Mozilla Firefox.