R语言:使用pheatmap调整列顺序同时保留拓扑结构
嘿,我之前也碰到过一模一样的需求,这就给你一步步拆解怎么实现:
核心思路
要保留原有聚类的拓扑结构同时调整列顺序,本质是调整聚类树的分支展示顺序,而不是重新聚类。我们需要先拿到原热图的聚类树,再按照需求调整树的分支顺序,最后让热图使用调整后的树和对应排列的数据列。
具体步骤
1. 先获取原聚类的树状图
先运行一次pheatmap,把聚类结果存下来,这样我们能拿到列的聚类树:
library(pheatmap) # 用示例数据演示,你替换成自己的矩阵就行 set.seed(123) mat <- matrix(rnorm(100), nrow = 10, ncol = 10) colnames(mat) <- paste0("Col", 1:10) # 生成初始热图,获取聚类结果 p <- pheatmap(mat, cluster_cols = TRUE) # 提取列的聚类树(hclust对象) col_tree <- p$tree_col
2. 确定符合拓扑结构的列顺序
关键注意点:你想要的列顺序必须符合原聚类的拓扑结构——不能把跨分支的列交叉排列,只能调整整个分支的展示顺序,或者分支内部的子顺序。比如:
- 你可以把聚类后的Group 2移到Group 1前面展示
- 可以调整某个子分支内的列顺序,但不能打乱分支的层次关系
举个例子,我们先把列分成2个聚类组,然后把Group 2放在前面:
# 把列聚类树分成2个组 col_groups <- cutree(col_tree, k = 2) # 定义新的列顺序:先展示Group 2,再展示Group 1 new_col_order <- c(names(col_groups[col_groups == 2]), names(col_groups[col_groups == 1]))
3. 调整聚类树的顺序匹配新列顺序
这里需要用到dendextend包来调整树状图的分支顺序,先安装并加载它:
install.packages("dendextend") library(dendextend) # 把hclust对象转成dendrogram,方便调整 col_dend <- as.dendrogram(col_tree) # 按照我们的新列顺序重新排列树的分支 col_dend_reordered <- reorder(col_dend, w = match(colnames(mat), new_col_order)) # 再转回hclust格式,供pheatmap使用 col_tree_reordered <- as.hclust(col_dend_reordered)
4. 绘制调整后的热图
最后,按照新顺序排列数据列,并用调整后的聚类树绘制热图(记得关闭自动列聚类,避免重新聚类):
# 按新顺序排列矩阵的列 mat_reordered <- mat[, new_col_order] # 绘制热图,指定自定义的列聚类树 pheatmap(mat_reordered, cluster_cols = FALSE, tree_col = col_tree_reordered)
这样出来的热图,列顺序是你想要的,顶部的树状图拓扑结构和原来完全一致,只是分支的展示顺序跟着列同步调整了。
内容的提问来源于stack exchange,提问作者Sam Vanbergen
相关产品推荐
相关产品推荐

