Learn R Programming

robustbase (version 0.92-5)

classPC: Compute Classical Principal Components via SVD or Eigen

Description

Compute classical principal components (PC) via SVD (svd or eigenvalue decomposition (eigen) with non-trivial rank determination.

Usage

classPC(x, scale = FALSE, center = TRUE, signflip = TRUE,
        via.svd = n > p, scores = FALSE)

Arguments

x
a numeric matrix.
scale
logical indicating if the matrix should be scaled; it is mean centered in any case (via scale(*, scale=scale)c
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
scores
logical indicating

Value

  • a list with components
  • rankthe (numerical) matrix rank of x; an integer number, say $k$, from 0:min(dim(x)). In the $n > p$ case, it is rankMM(x).
  • eigenvaluesthe $k$ eigenvalues, in the $n > p$ case, proportional to the variances.
  • loadingsthe loadings, a $p \times k$ matrix.
  • scoresif the scores argument was true, the $n \times k$ matrix of scores, where $k$ is the rank above.
  • centera numeric $p$-vector of means, unless the center argument was false.
  • scaleif the scale argument was not false, the scale used, a $p$-vector.

concept

PCA

See Also

In spirit very similar to R's standard prcomp and princomp, one of the main differences being how the rank is determined via a non-trivial tolerance.

Examples

Run this code
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
stopifnot(classPC(x, center=FALSE)$rank == min(dim(x)))
ii <- names(pcx); ii <- ii[ii != "scores"]
stopifnot(all.equal(pcx[ii], pc2[ii], tol=0),
	  all.equal(pcx, pcS, tol=1e-8),
	  length(pc.x$center) == 10, identical(pc0$center, FALSE),
          all.equal(crossprod(pcx $loadings), diag(9)),
          all.equal(crossprod(pc.x$loadings), diag(10)),
          all.equal(colSums(abs(pcx$loadings)),
                    c(2.69035673, 2.78449399, 3.00148438,
                      2.9016688,  2.49400759, 2.90477204,
                      3.01639807, 2.4217181, 2.64665957)),
	  length(pc0$scale) == 12)

Run the code above in your browser using DataLab