Is it correct if I multiplied datatest with the loadings from the datatraining and get the scores of pca datatesting?
It depends on whether the you set cor = TRUE
in your call to princomp
. In any case, just use predict
which will make sure to potentially scale, potentially center, and rotate the data. The code below shows both the "manual" way to get the result and by using predict.princomp
pc.cr <- princomp(USArrests, cor = TRUE)
loadings(pc.cr)
#R
#R Loadings:
#R Comp.1 Comp.2 Comp.3 Comp.4
#R Murder 0.536 0.418 0.341 0.649
#R Assault 0.583 0.188 0.268 -0.743
#R UrbanPop 0.278 -0.873 0.378 0.134
#R Rape 0.543 -0.167 -0.818
#R
#R Comp.1 Comp.2 Comp.3 Comp.4
#R SS loadings 1.00 1.00 1.00 1.00
#R Proportion Var 0.25 0.25 0.25 0.25
#R Cumulative Var 0.25 0.50 0.75 1.00
# get rotation without `princomp`
loads <- local({
# use same scales as `princomp`
X <- scale(as.matrix(USArrests), scale =
sapply(USArrests, function(x) sqrt(mean((x - mean(x))^2))))
C <- cov(X)
out <- eigen(C)$vectors
dimnames(out) <- list(colnames(USArrests), paste0("PC", seq_len(ncol(X))))
# we save the output from scale to later
attributes(out) <- c(attributes(out), attributes(X)[c(
"scaled:scale", "scaled:center")])
out
})
loads # loadings are unique up to sign
#R PC1 PC2 PC3 PC4
#R Murder -0.536 0.418 -0.341 0.649
#R Assault -0.583 0.188 -0.268 -0.743
#R UrbanPop -0.278 -0.873 -0.378 0.134
#R Rape -0.543 -0.167 0.818 0.089
#R attr(,"scaled:scale")
#R Murder Assault UrbanPop Rape
#R 4.31 82.50 14.33 9.27
#R attr(,"scaled:center")
#R Murder Assault UrbanPop Rape
#R 7.79 170.76 65.54 21.23
# there is a predict function for class
class(pc.cr)
#R [1] "princomp"
# predict for first two rows
predict(pc.cr, newdata = USArrests[1:2, ])
#R Comp.1 Comp.2 Comp.3 Comp.4
#R Alabama 0.986 1.13 0.444 0.156
#R Alaska 1.950 1.07 -2.040 -0.439
# reproduce the above
tmp <- scale(
USArrests[1:2, ], scale = attr(loads, "scaled:scale"),
center = attr(loads, "scaled:center"))
tmp %*% loads # they are unique up to sign
#R PC1 PC2 PC3 PC4
#R Alabama -0.986 1.13 -0.444 0.156
#R Alaska -1.950 1.07 2.040 -0.439