Confused by an article on princomp in R

https://www.datacamp.com/tutorial/pca-analysis-r

The article says:

We need to center/scale the numeric variables, compute the correlation/covariance matrix and then invoke princomp with that correlation/covariance matrix as the first argument.

The help page for princomp says:

     ## Default S3 method:
princomp(x, cor = FALSE, scores = TRUE, covmat = NULL,
subset = rep_len(TRUE, nrow(as.matrix(x))), fix_sign = TRUE, ...)

x: a numeric matrix or data frame which provides the data for
the principal components analysis.

covmat: a covariance matrix, or a covariance list as returned by
‘cov.wt’ (and ‘cov.mve’ or ‘cov.mcd’ from package ‘MASS’).
If supplied, this is used rather than the covariance matrix
of ‘x’.


If I understand correctly, we may do one of 2 things.

1. Invoke this function with only one unnamed argument which will then be understood by the program as the input x. The program will automatically compute the covariance matrix and then do it's eigen decomposition to compute the eigenvalues/eigenvectors of the covariance matrix of x which in turn will give us the Principal Components of x.

2. Invoke this function with only one argument which is covmat = the covariance matrix. This will again do an eigen decomposition of this matrix and return the eigenvalues/eignevectors of this matrix ( which is the correlation or covariance matrix of x, because we chose it to be so).

We cannot: Compute the correlation / covariance matrix and then invoke the princomp function with this matrix as the only unnamed argument. If we do so the program will think that correlation/covariance matrix as the matrix x and will internally compute the eigenvalues / eignenvectors of the correlation/covariance matrix of the correlation/covariance mattrix of x.

This will return the PCs of the correlation/covariance matrix and not the principal componenets of x.

Here is a small simulation:

These 2 are kind of the same:

> princomp(mtcars)
Call:
princomp(x = mtcars)

Standard deviations:
Comp.1      Comp.2      Comp.3      Comp.4      Comp.5      Comp.6
134.3827868  37.5472829   3.0226511   1.2860724   0.8922099   0.6530910
Comp.7      Comp.8      Comp.9     Comp.10     Comp.11
0.3037193   0.2814568   0.2467490   0.2073344   0.1952988

11  variables and  32 observations.
>

> princomp(covmat = cov(mtcars))
Call:
princomp(covmat = cov(mtcars))

Standard deviations:
Comp.1      Comp.2      Comp.3      Comp.4      Comp.5      Comp.6
136.5330479  38.1480776   3.0710166   1.3066508   0.9064862   0.6635411
Comp.7      Comp.8      Comp.9     Comp.10     Comp.11
0.3085791   0.2859604   0.2506973   0.2106519   0.1984238

11  variables and  NA observations.
>


This is different to the above 2:

> princomp(cov(mtcars))
Call:
princomp(x = cov(mtcars))

Standard deviations:
Comp.1       Comp.2       Comp.3       Comp.4       Comp.5       Comp.6
5.168233e+03 4.334259e+02 2.724862e+00 5.090709e-01 2.042575e-01 1.263206e-01
Comp.7       Comp.8       Comp.9      Comp.10      Comp.11
2.649914e-02 2.136515e-02 1.893399e-02 1.273819e-02 0.000000e+00

11  variables and  11 observations.
>



Also, notice how the program above says:

princomp(x = cov(mtcars))


Do I misunderstand?

Note : I did not scale the variables like the author in the above mentioned page did and perhaps that made a difference. So I did the following experiment to test if that makes a difference.

Once again, the first 2 seem similar while the third seems different.

> princomp(scale(mtcars))
Call:
princomp(x = scale(mtcars))

Standard deviations:
Comp.1    Comp.2    Comp.3    Comp.4    Comp.5    Comp.6    Comp.7    Comp.8
2.5301952 1.6023860 0.7794853 0.5110504 0.4652615 0.4527513 0.3619876 0.3450518
Comp.9   Comp.10   Comp.11
0.2732013 0.2245202 0.1461353

11  variables and  32 observations.
> princomp(covmat = cor(scale(mtcars)))
Call:
princomp(covmat = cor(scale(mtcars)))

Standard deviations:
Comp.1    Comp.2    Comp.3    Comp.4    Comp.5    Comp.6    Comp.7    Comp.8
2.5706809 1.6280258 0.7919579 0.5192277 0.4727061 0.4599958 0.3677798 0.3505730
Comp.9   Comp.10   Comp.11
0.2775728 0.2281128 0.1484736

11  variables and  NA observations.
> princomp(cor(scale(mtcars)))
Call:
princomp(x = cor(scale(mtcars)))

Standard deviations:
Comp.1      Comp.2      Comp.3      Comp.4      Comp.5      Comp.6
1.992444019 0.762563719 0.164481730 0.079889308 0.065557778 0.052541093
Comp.7      Comp.8      Comp.9     Comp.10     Comp.11
0.040670837 0.024829720 0.022722621 0.006649006 0.000000000

11  variables and  11 observations.
$$$$

• Almost all of those "learn data science" websites are riddled with errors and inaccuracies Commented Jun 27, 2023 at 8:55

• If some online tutorial disagrees with the official documentation of the software, almost always you should trust the documentation. What the documentation says is:

Description

princomp performs a principal components analysis on the given numeric data matrix and returns the results as an object of class princomp.

Usage

princomp(x, ...)

## S3 method for class 'formula'
princomp(formula, data = NULL, subset, na.action, ...)

## Default S3 method:
princomp(x, cor = FALSE, scores = TRUE, covmat = NULL,
subset = rep_len(TRUE, nrow(as.matrix(x))), fix_sign = TRUE, ...)

## S3 method for class 'princomp'
predict(object, newdata, ...)


Arguments

formula a formula with no response variable, referring only to numeric variables.

data an optional data frame (or similar: see model.frame) containing the variables in the formula formula. By default the variables are taken from environment(formula).

[...]

x a numeric matrix or data frame which provides the data for the principal components analysis.

cor a logical value indicating whether the calculation should use the correlation matrix or the covariance matrix. (The correlation matrix can only be used if there are no constant variables.)

[...]

covmat a covariance matrix, or a covariance list as returned by cov.wt (and cov.mve or cov.mcd from package MASS). If supplied, this is used rather than the covariance matrix of x.

[...]

So it can be called either with raw data or the given covariance or correlation matrix (with cor=TRUE).

• The tutorial calculates the principal components analysis of the correlation matrix. Sure, you can do this, but in most cases, you would be interested in doing PCA of the raw data, rather than the correlation matrix.

• The tutorial uses the correlation matrix without the argument cor=TRUE. This makes sense if the author wants a PCA of the correlation matrix used as data, but is incorrect if they mean providing the correlation matrix (the covmat` argument).

• The tutorial incorrectly suggests that you should scale the data before calculating the correlations. This is not needed, as correlation already is a normalized covariance.

So the moral is that you should not trust everything you read on the internet.