如何在Factoextra绘制的PCA图中筛选指定BIN个体?
解决PCA图筛选指定样本(保留全数据PCA结果)的方法
核心思路:先基于完整数据集计算PCA,再在绘图阶段筛选目标样本,这样主成分的变异结构和原图完全一致,只是只显示指定BIN的个体。
步骤1:基于全数据计算PCA
假设你的数据集df包含:测量数据列、标本名称列、BIN列。先剥离测量数据,计算PCA(这里给出两种常用实现方法):
方法1:基础R的prcomp
# 提取测量数据(排除标本名称和BIN列) measure_data <- df[, !names(df) %in% c("标本名称", "BIN")] # 计算PCA(标准化数据,保证变量权重一致) pca_result <- prcomp(measure_data, scale. = TRUE)
方法2:FactoMineR包的PCA(适配后续factoextra绘图)
library(FactoMineR) # 计算PCA,关闭默认绘图 pca_result <- PCA(measure_data, scale.unit = TRUE, graph = FALSE)
步骤2:合并PCA得分与样本标签
把PCA主成分得分和BIN、标本名称合并,方便后续筛选:
# 提取PCA得分并关联样本标签 pca_scores <- as.data.frame(pca_result$x) pca_scores$BIN <- df$BIN pca_scores$标本名称 <- df$标本名称
步骤3:筛选目标BIN的样本
指定要保留的BIN,筛选得分数据:
target_bins <- c("ACZ5516", "ADF3772") filtered_scores <- pca_scores[pca_scores$BIN %in% target_bins, ]
步骤4:绘制筛选后的PCA图
方法1:用ggplot2自定义绘图
library(ggplot2) # 计算主成分解释率 pc1_var <- round(pca_result$sdev[1]^2 / sum(pca_result$sdev^2) * 100, 1) pc2_var <- round(pca_result$sdev[2]^2 / sum(pca_result$sdev^2) * 100, 1) ggplot(filtered_scores, aes(x = PC1, y = PC2, color = BIN)) + geom_point(size = 3) + labs(x = paste0("主成分1 (", pc1_var, "%)"), y = paste0("主成分2 (", pc2_var, "%)")) + theme_bw()
方法2:用factoextra快速绘图(适配FactoMineR结果)
如果用FactoMineR计算PCA,可直接用fviz_pca_ind的select.ind参数,注意传入目标样本的行索引:
library(factoextra) # 获取目标BIN对应的行索引 target_indices <- which(df$BIN %in% target_bins) # 绘制仅含目标样本的PCA图 fviz_pca_ind(pca_result, select.ind = target_indices, col.ind = df$BIN[target_indices], repel = TRUE)
常见问题说明
- 为什么用数据子集做PCA不行?:子集数据会重新计算主成分,其方差结构基于部分样本,和全数据的PCA结果完全不同,不符合“与原图一致”的需求。
- 之前用
select.ind没显示样本?:大概率是参数传入错误——select.ind需要的是样本的行索引,而非BIN的字符串值,按上述方法获取target_indices再传入即可解决。
内容的提问来源于stack exchange,提问作者D.Underwood
相关产品推荐
相关产品推荐

