PCA in R: Choose Principal Components by Variance Explained
Start with the variance, then decide what to keep
A PCA run can shrink a wide set of correlated measurements into a few readable axes. The useful question isn’t just how to run it in R; it’s whether those axes preserve enough of the original data to make the reduction worthwhile. For the built-inUSArrests dataset, the first two components explain 86.75% of total variance. That’s a strong case for viewing the data in two dimensions, though it doesn’t settle every choice: the Kaiser rule would keep only the first component, while the scree plot and cumulative variance point toward keeping two. This disagreement is a good reminder that component-selection rules are guides, not verdicts.
Here’s a runnable starting point. R’s prcomp() centers and scales the variables when asked, performs the decomposition, and returns both the variable loadings and observation scores. The optional ggplot2 and factoextra packages help with plots.
Complete Code — Copy, Paste, Run# Complete PCA in R script -- copy, paste, run top to bottom
# 1. Install and load required packages
install.packages(c("ggplot2", "factoextra"))
library(ggplot2)
library(factoextra)
#2. Load the data and check assumptions
data(USArrests)
str(USArrests)
cor(USArrests)
apply(USArrests, 2, shapiro.test)
#3. Scale the data (prcomp() can also do this inline with scale = TRUE)
data_scaled <- scale(USArrests)
head(data_scaled)
#4. Run PCA
pca <- prcomp(USArrests, scale = TRUE)
summary(pca)
pca$rotation
#5. Decide how many components to keep
plot(pca$sdev^2, type = "b", xlab = "Principal Component", ylab = "Eigenvalue", main = "Scree Plot")
fviz_eig(pca, addlabels = TRUE, barfill = "steelblue", barcolor = "steelblue",
linecolor = "firebrick", main = "Scree Plot: Variance Explained by Component")
pve <- pca$sdev^2 / sum(pca$sdev^2)
cum_pve <- cumsum(pve)
plot(cum_pve, type = "b", xlab = "Principal Component",
ylab = "Cumulative Proportion of Variance Explained")
#6. Visualize results
biplot(pca, scale = 0)
fviz_pca_biplot(pca,
geom.ind = "point",
col.ind = as.factor(state.region),
palette = "jco",
addEllipses = TRUE,
col.var = "black",
repel = TRUE,
legend.title = "Region") +
theme_minimal()Jump to the full step-by-step explanation ↓What PCA gives you
PCA takes correlated variables and expresses them as a smaller set of uncorrelated principal components. The first component captures as much variance as possible; each later component captures the largest remaining share while staying orthogonal to those already found. That makes PCA useful when you need to simplify a dataset or inspect its broad patterns in a two-dimensional plot. The first twoUSArrests components account for 86.75% of the variance. The tutorial’s interpretation is also concrete: PC1 mainly reflects violent crime, while PC2 largely reflects urbanization. Those labels help make the plot readable, but they remain interpretations of the component loadings rather than original measurements.
The article is written by Dr Zubair Goraya, who describes a PhD-level background in statistics and years of R work in statistical consulting and research. He says he has helped thesis and dissertation students address practical questions such as how many components to retain, how to interpret prcomp(), and how to make a biplot.
Why use prcomp()?
The base R function prcomp() uses singular value decomposition (SVD), a numerically stable way to calculate PCA. It returns the rotation matrix in pca$rotation for variable loadings and the scores in pca$x for observations. The older princomp() function uses a different route and is less numerically stable.
PCA is intended for numeric, continuous variables. The example uses USArrests, which records violent crime rates and urban population percentages for all 50 US states in 1973. It’s also used in An Introduction to Statistical Learning, giving readers a familiar reference for checking results.
The tutorial checks variable types, pairwise correlations, and normality with str(), cor(), and Shapiro-Wilk tests. Its reported p-values are 0.067 for Murder, 0.041 for Assault, 0.439 for UrbanPop, and 0.025 for Rape. The article says UrbanPop is the only variable that does not significantly depart from normality, then proceeds with all four variables, citing PCA’s tolerance of mild non-normality at a sample size of 50.
One detail deserves care: the table labels Murder’s result “Significant? Yes” despite its p-value of 0.067, which is above the stated 0.05 cutoff. The prose says the other three variables have p-values below 0.05, consistent with the remaining entries.
Scaling matters, and component rules can disagree
The crime rates are measured per 100,000 residents, while UrbanPop is a percentage. Without scaling, the larger numerical values for Assault could dominate the result because of their units. Settingscale = TRUE in prcomp() handles standardization; the script also shows how to inspect manually scaled values with scale(USArrests).
There’s no universal cutoff for how many components to keep. The tutorial compares a scree plot, the Kaiser rule, and cumulative variance. The Kaiser rule retains components with eigenvalues above 1; here PC1’s eigenvalue is 2.480, while PC2 is just below the threshold at 0.990. Yet PC2 explains nearly a quarter of the variance and has an interpretable urbanization signal. A strict cutoff would discard it, even though the other methods support keeping it.
The cumulative variance reaches 86.75% with two components, above the common 80–90% target range cited in the article. On this dataset, retaining PC1 and PC2 is the more defensible choice across the methods considered.
Plots make the result easier to inspect
A biplot places observation scores and variable loadings on the same PC1/PC2 plane. Base R can draw one withbiplot(pca, scale = 0). For more styling, factoextra provides fviz_eig() for a scree plot and fviz_pca_biplot() for a biplot with regional colors, ellipses, and repelled labels. Both return ggplot objects that can be extended with standard themes and layers.
The article’s wider point is practical: PCA and factor analysis are different tools, and the choice between them depends on what you want to learn from the data. The tutorial promises a comparison later on.
RStudioDataLab first published this article and contributed it to R-bloggers. Report an issue with this page. Want to share your own work on R-bloggers? Submit a blog, or use R-posts if you don’t have one.

The regional pattern in this biplot follows the interpretation of the loadings: Southern states tend toward higher PC1 scores, associated here with violent crime, while Western states vary more along PC2, the axis associated with urbanization. That alignment is a useful check that the score plot and the component interpretation tell a consistent story.
PCA and Factor Analysis Answer Different Questions
Both methods compress information across several measurements, which is why they’re often confused. The choice depends on what you’re trying to learn. PCA summarizes observed data; Factor Analysis tests whether shared underlying traits can account for relationships among observed measures. Treating them as interchangeable can undermine a thesis methodology.
| PCA | Factor Analysis | |
|---|---|---|
| Goal | Reduce dimensions by maximizing explained variance | Find latent constructs that may explain the observed variables |
| Variance modeled | All variance, including common and unique variance | Shared variance; unique and error variance are separated |
| Latent-variable assumption | None; PCA is a mathematical transformation | Assumes observed variables reflect underlying factors |
| Rotation | Not usually applied | Often rotated, for example with varimax or promax, to aid interpretation |
| R function | prcomp() | factanal() or psych::fa() |
| Best suited to | Dimension reduction and visualizing data structure | Testing a theory about the constructs behind measured items |
If your survey is intended to measure anxiety, job satisfaction, or brand loyalty, Exploratory Factor Analysis is generally the better fit. PCA can still summarize those responses, but it doesn’t model the psychological construct as a hidden cause of the answers. See this guide to Exploratory Factor Analysis.
Reporting a PCA in APA Style
A useful report explains the preprocessing, the retention decision, and what each retained component represents. Here’s a template based on the USArrests example:
Sample write-up:
“A principal component analysis (PCA) was conducted on four crime-related variables (Murder, Assault, UrbanPop, Rape) using the prcomp() function in R (R Core Team). Variables were standardized before analysis. Applying the Kaiser criterion (eigenvalue > 1), a scree plot, and an 80% cumulative-variance threshold, two components were retained. PC1 explained 62.0% of the variance and was driven mainly by Murder, Assault, and Rape (loadings of -0.54, -0.58, and -0.54, respectively), indicating a general violent-crime dimension. PC2 accounted for a further 24.7% and loaded almost entirely on UrbanPop (0.87), reflecting an urbanization dimension. Together, the components explained 86.75% of total variance.”
Include the loadings table from Step 3 and a scree plot or cumulative-variance figure in a formal report. Those materials show how you reached the retention decision; reporting only the final component count leaves readers without that evidence.
Put the Component Scores to Work
The scores in pca$x can feed later analyses. You might use them as inputs to k-means clustering, reducing the data to uncorrelated dimensions first, or inspect multicollinearity before fitting a regression model. PCA is most useful when the reduced representation suits the next question; fewer variables alone don’t guarantee a better analysis.
Practical Questions About PCA in R
Which R package should I use?
For most analyses, the built-in prcomp() function from stats is enough and is generally preferred to princomp() for numerical stability. Add factoextra for richer plots. For broader multivariate exploratory analysis, including correspondence analysis, consider FactoMineR; see this overview of exploratory analysis.
How can I plot PCA results?
Use plot(pca) for a quick scree plot, biplot(pca) to show scores and loadings in base R, or factoextra::fviz_pca_biplot(pca) for a customizable ggplot2 plot with colors, ellipses, and labels.
What does prcomp() return?
Its prcomp object contains sdev (component standard deviations), rotation (loadings), x (observation scores), and center and scale (the values used to center and scale the input).
How do prcomp() and princomp() differ?
princomp() uses eigen decomposition of the covariance matrix. prcomp() applies singular value decomposition (SVD) directly to the data matrix, which offers slightly better numerical accuracy; R’s documentation recommends prcomp().
How many components should I retain?
There’s no single cutoff that works for every dataset. Compare the scree plot elbow, the Kaiser rule (eigenvalue > 1), and cumulative variance, often judged against an 80–90% target. These methods can disagree, so explain why your chosen solution fits the analysis.
Can PCA handle categorical variables?
Standard PCA expects numeric, continuous variables. For categorical data, use Multiple Correspondence Analysis (MCA), available as FactoMineR::MCA(). MCA applies dimensionality reduction to a contingency table of category frequencies; this guide discusses categorical data.
What mistakes should I watch for?
Skipping scale = TRUE can let variables with large numerical ranges dominate PC1. Missing values and outliers can also distort the covariance structure. Finally, don’t read a scree-plot elbow mechanically or ignore loading signs when interpreting a component.
Where is PCA used?
Applications include image compression, facial-recognition feature extraction, gene-expression analysis in bioinformatics, customer segmentation in marketing, and preprocessing before clustering or regression to remove multicollinearity.
Conclusion
The key judgment in PCA isn’t running prcomp(); it’s deciding what the components mean and how many deserve to stay. This workflow covers assumption checks, scaling, fitting the model, comparing three retention methods, plotting with base R and ggplot2, distinguishing PCA from Factor Analysis, and reporting results in APA style. Apply the same steps to your own data by replacing USArrests with your data frame, then justify each analytical choice in the context of your question.
If you’re working on PCA, Factor Analysis, or another multivariate method for a thesis or dissertation and want a second opinion on your output, get in touch below.
Get PCA / Statistics Help on WhatsApp Join Our CommunityTo leave a comment for the author, visit RStudioDataLab. R-bloggers.com offers daily email updates on R news, tutorials about learning R, and other topics. For data science jobs, visit R-users. Authors can submit a blog to R-bloggers, or use R-posts if they don’t have one.
Continue reading: PCA in R: Principal Component Analysis Step-by-Step (prcomp + ggplot2)