关于R语言prcomp做PCA绘图:轴百分比显示及指定PC组合绘图的问题
Hey there! Let's tackle your two PCA plotting needs step by step. First, we'll store your PCA result properly to reuse it (instead of calling prcomp() every time), then add variance percentages to your axes, and finally create biplots for any PC pair you want.
Step 1: Store PCA Result & Calculate Variance Explained
First, let's save your PCA output and compute the variance explained percentage for each principal component. This will make it easy to reference later in plots.
# Replace 'x' with your actual dataset pca_result <- prcomp(x, scale.=TRUE) # Scale=TRUE is critical for PCA if variables have different units # Extract variance explained percentages (rounded to 2 decimal places) var_exp_pct <- round(summary(pca_result)$importance["Proportion of Variance", ] * 100, 2)
Step 2: Add Variance Explained to Plot Axes
A. Scree Plot (Default PCA Plot)
The default plot(pca_result) shows eigenvalues (variance) per PC. To add variance percentages as annotations and improve axis labels:
plot(pca_result, type="l", main="Scree Plot", ylab="Variance Explained", xlab="Principal Component") # Add text labels for variance percentage above each point text(x=1:length(var_exp_pct), y=pca_result$sdev^2, labels=paste0(var_exp_pct, "%"), pos=3)
B. PCA Scores Scatter Plot
If you want a scatter plot of PC scores (e.g., PC1 vs PC2) with axis labels showing variance percentages:
# Extract PCA scores scores <- pca_result$x # Plot PC1 vs PC2 with custom axis labels plot(scores[, c("PC1", "PC2")], xlab=paste0("PC1 (", var_exp_pct["PC1"], "% variance)"), ylab=paste0("PC2 (", var_exp_pct["PC2"], "% variance)"), main="PCA Scores: PC1 vs PC2")
C. Biplot with Variance Explained Labels
The default biplot() doesn't include variance percentages, but we can pass custom xlab and ylab arguments to fix that:
biplot(pca_result, xlab=paste0("PC1 (", var_exp_pct["PC1"], "% variance)"), ylab=paste0("PC2 (", var_exp_pct["PC2"], "% variance)"), main="Biplot: PC1 vs PC2")
Step 3: Create Biplots for Specific PC Combinations
To plot pairs like PC2 vs PC3, use the choices argument in biplot(). This takes a vector of two integers specifying which PCs to use for the x and y axes.
# Biplot for PC2 (x-axis) vs PC3 (y-axis) biplot(pca_result, choices=c(2, 3), # First number = x-axis PC, second = y-axis PC xlab=paste0("PC2 (", var_exp_pct["PC2"], "% variance)"), ylab=paste0("PC3 (", var_exp_pct["PC3"], "% variance)"), main="Biplot: PC2 vs PC3")
You can swap the numbers to get any combination—for example, choices=c(3,1) would plot PC3 vs PC1.
Full Example with Iris Dataset
Here's a complete, runnable example using the built-in iris dataset to test everything:
data(iris) x <- iris[, 1:4] # Use numerical features # Run PCA pca_result <- prcomp(x, scale.=TRUE) var_exp_pct <- round(summary(pca_result)$importance["Proportion of Variance", ] * 100, 2) # Scree plot with annotations plot(pca_result, type="l", main="Scree Plot - Iris Dataset", ylab="Variance", xlab="Principal Component") text(x=1:4, y=pca_result$sdev^2, labels=paste0(var_exp_pct, "%"), pos=3) # PC1 vs PC2 scores plot with species colors scores <- pca_result$x plot(scores[, c("PC1", "PC2")], xlab=paste0("PC1 (", var_exp_pct["PC1"], "% variance)"), ylab=paste0("PC2 (", var_exp_pct["PC2"], "% variance)"), main="PCA Scores: PC1 vs PC2 - Iris", col=iris$Species, pch=16) legend("topright", legend=levels(iris$Species), col=1:3, pch=16) # PC1 vs PC2 biplot biplot(pca_result, xlab=paste0("PC1 (", var_exp_pct["PC1"], "% variance)"), ylab=paste0("PC2 (", var_exp_pct["PC2"], "% variance)"), main="Biplot: PC1 vs PC2 - Iris") # PC2 vs PC3 biplot biplot(pca_result, choices=c(2,3), xlab=paste0("PC2 (", var_exp_pct["PC2"], "% variance)"), ylab=paste0("PC3 (", var_exp_pct["PC3"], "% variance)"), main="Biplot: PC2 vs PC3 - Iris")
内容的提问来源于stack exchange,提问作者M. arman

