如何基于物种分布数据构建PCA并验证PCA1与PCA2的分类效果?
解决PCA散点图拉伸及分类效果展示问题
问题根源分析
你当前的PCA分析存在两个核心问题:
- 误用了原始物种数据集
data做PCA,而非提取到的环境变量矩阵variables,导致PCA维度不是基于环境变量的变异 - 可视化时未结合物种的
presence_absence分类标签,所以无法体现PCA对存在/缺失样本的区分能力
修正步骤及代码
1. 整合环境变量与分类标签
先把提取到的环境变量矩阵和物种的存在/缺失标签合并,确保数据对齐:
# 将环境变量矩阵转为数据框,合并物种存在/缺失标签 env_data <- as.data.frame(variables) env_data$presence_absence <- data$presence_absence # 移除含NA的行(和之前的预处理对齐) env_data_clean <- na.omit(env_data)
2. 基于环境变量重新执行PCA
用环境变量做PCA,同时保留分类标签用于后续可视化:
# 提取环境变量列(排除presence_absence) env_vars <- env_data_clean[, !colnames(env_data_clean) %in% "presence_absence"] # 标准化数据并执行PCA(scale=TRUE确保变量标准化) pca_results <- prcomp(env_vars, scale. = TRUE) # 提取PCA得分并合并分类标签 pca_scores <- as.data.frame(pca_results$x[, c(1, 2)]) pca_scores$presence_absence <- factor(env_data_clean$presence_absence, levels = c(0,1), labels = c("缺失", "存在"))
3. 生成带分类效果的PCA散点图
用ggplot2绘制带颜色区分的散点图,同时添加方差解释率到坐标轴标签:
# 计算PC1和PC2的方差解释率 pc1_var <- round(pca_results$sdev[1]^2 / sum(pca_results$sdev^2) * 100, 1) pc2_var <- round(pca_results$sdev[2]^2 / sum(pca_results$sdev^2) * 100, 1) # 绘制优化后的PCA散点图 scatter_plot <- ggplot(pca_scores, aes(x = PC1, y = PC2, color = presence_absence)) + geom_point(alpha = 0.7, size = 1.5) + # 调整点的透明度和大小,避免重叠 scale_color_manual(values = c("缺失" = "gray", "存在" = "blue")) + labs(title = "基于环境变量的PCA散点图(Solanum acaule)", x = paste0("主成分1 (", pc1_var, "% 方差解释)"), y = paste0("主成分2 (", pc2_var, "% 方差解释)"), color = "物种分布") + theme_minimal() + theme(plot.title = element_text(hjust = 0.5, size = 14), axis.title = element_text(size = 12), legend.title = element_text(size = 12)) print(scatter_plot)
4. 可选:添加PCA载荷图(展示环境变量对主成分的贡献)
如果需要进一步解释PCA的意义,可以绘制载荷图:
# 提取PCA载荷 pca_loadings <- as.data.frame(pca_results$rotation[, c(1, 2)]) pca_loadings$variable <- rownames(pca_loadings) # 绘制载荷图 loading_plot <- ggplot(pca_loadings, aes(x = PC1, y = PC2)) + geom_segment(aes(x = 0, y = 0, xend = PC1, yend = PC2), arrow = arrow(length = unit(0.2, "cm")), color = "darkred") + geom_text(aes(label = variable), hjust = 1.2, vjust = 1.2, size = 4) + labs(title = "PCA载荷图(环境变量贡献)", x = paste0("主成分1 (", pc1_var, "% 方差解释)"), y = paste0("主成分2 (", pc2_var, "% 方差解释)")) + theme_minimal() + theme(plot.title = element_text(hjust = 0.5, size = 14)) print(loading_plot)
关键说明
- 确保PCA输入是环境变量矩阵,而非原始物种数据(原始数据中的经纬度、存在标签不属于环境变量,会干扰PCA结果)
- 用
factor转换分类标签,让图形的图例更清晰 - 添加方差解释率可以直观展示主成分的信息量
- 调整点的透明度和大小可以缓解点重叠问题,避免出现“拉伸的点”的视觉效果
内容的提问来源于stack exchange,提问作者Sophia
相关产品推荐
相关产品推荐

