ann_colors <- list( Cluster = c( "1" = "#E41A1C", "2" = "#4DAF4A", "3" = "#377EB8", "4" = "#FF7F00", "5" = "#984EA3" ), Gender = c( "M" = "#A8CAE8", "F" = "#F58383" ), Age = c( ">=65" = "#81B3A9", "<65" = "#B3C6BB" ), 'Histologic type' = c( "CSCLC" = "#715EA9", "Pure SCLC" = "#cac0e1" ), Smoking = c( "yes" = "#6a9ace", "no" = "#abdaec", "unknown" = "#d4d4d4" ), 'TNM stage' = c( "I"="#FFD47F", "II"="#F7C1CF", "III"="#7B92C7", "IV"="#ADD9EE" ) ) 我有这些分组信息,现在想以cluster顺序为主排列热图
时间: 2025-06-18 21:14:49 浏览: 5
<think>我们有两个任务:1.按照用户自定义的cluster顺序排列热图(不进行聚类)2.同时保留其他分组信息(如Gender,Age等)的注释有两种主要方案:pheatmap和ComplexHeatmap。根据用户之前的问题,他可能已经尝试过pheatmap,现在希望有更灵活的解决方案(尤其是当基因名过多时,ComplexHeatmap可以更好地处理标签重叠)。我们分别提供两种包的解决方案:方案一:使用pheatmap-步骤:手动排序矩阵->创建分组注释->设置间隔线->关闭聚类方案二:使用ComplexHeatmap(更强大,适合复杂注释和标签处理)-步骤:创建行和列的分组因子(按自定义顺序)->按因子顺序排序矩阵->添加注释->绘制热图(不聚类)考虑到用户提到基因名重叠的问题,ComplexHeatmap有更好的解决方案(如使用行标签的标记,只显示部分标签)。下面我们分别给出两种方法的代码示例。注意:用户的数据应包含表达矩阵(行是基因,列是样本),以及两个数据框:一个用于行分组(自定义cluster),另一个用于列分组(如Gender,Age等)。假设:-行分组(cluster)已经定义,并存储在向量row_clusters中(与基因名顺序相同)-列分组信息存储在数据框col_anno中,包含多个列(如Gender,Age,以及用户自定义的cluster分组)我们以ComplexHeatmap为主,因为其功能更强大,且能解决标签重叠问题。但为了完整性,我们先给出pheatmap的解决方案,再详细给出ComplexHeatmap的解决方案。注意:在ComplexHeatmap中,我们可以通过设置行和列的顺序来固定排列,同时添加多个注释层。同时,针对标签重叠问题,我们可以使用`row_names_gp`调整字体大小,或者使用`row_labels`选择性地显示标签(例如,只显示每个cluster的代表基因),或者使用`anno_mark`来标记选定的基因(但注意在RStudio中直接绘图可能有问题,需要导出为PDF等)。由于用户提到在RStudio中使用,我们也会注意关于`anno_mark`的警告信息(引用[3])。我们将分为以下步骤:1.准备数据2.定义自定义顺序(cluster分组)3.排序矩阵4.创建注释(包括cluster分组和其他临床信息)5.绘制热图(不聚类,按排序后的矩阵)下面分别用两种包实现:方案一:pheatmap```r#假设数据set.seed(123)expression_data<-matrix(rnorm(1000),nrow=100,dimnames=list(paste0("Gene",1:100),paste0("Sample",1:10)))#行分组(假设有3个cluster,但注意这里每个基因属于哪个cluster是已知的)row_clusters<-rep(c("Cluster1","Cluster2","Cluster3"),times=c(30,40,30))names(row_clusters)<-rownames(expression_data)#列分组信息(包括自定义的列cluster和其他临床信息)#列自定义clustercol_clusters<-rep(c("GroupA","GroupB"),each=5)#其他临床信息(例如Gender,Age)col_anno<-data.frame(Cluster=col_clusters,Gender=sample(c("Male","Female"),10,replace=TRUE),Age=sample(20:80,10,replace=TRUE))rownames(col_anno)<-colnames(expression_data)#行注释(只有cluster)row_anno<-data.frame(GeneCluster=row_clusters)rownames(row_anno)<-rownames(expression_data)#自定义颜色ann_colors<-list(GeneCluster=c(Cluster1="red",Cluster2="blue",Cluster3="green"),Cluster=c(GroupA="orange",GroupB="purple"),Gender=c(Male="lightblue",Female="pink"),Age=colorRampPalette(c("white","brown"))(100)#连续型颜色)#按自定义顺序排序矩阵#行排序:先按cluster分组排序,然后在组内按基因名排序(或保持原顺序)row_order<-order(match(row_clusters,c("Cluster1","Cluster2","Cluster3")))col_order<-order(match(col_clusters,c("GroupA","GroupB")))sorted_expr<-expression_data[row_order,col_order]#计算分组间隔(行和列)row_gaps<-cumsum(table(row_clusters)[c("Cluster1","Cluster2","Cluster3")])col_gaps<-cumsum(table(col_clusters)[c("GroupA","GroupB")])#绘制热图library(pheatmap)pheatmap(sorted_expr,cluster_rows=FALSE,cluster_cols=FALSE,annotation_row=row_anno,annotation_col=col_anno,annotation_colors=ann_colors,gaps_row=row_gaps[-length(row_gaps)],#每组后加间隔,去掉最后一个累计和(因为不需要在最后加间隔)gaps_col=col_gaps[-length(col_gaps)],show_rownames=FALSE,#基因太多,不显示行名main="ClinicalHeatmap(pheatmap)")```方案二:ComplexHeatmap(推荐)```r#安装和加载#if(!require("BiocManager",quietly=TRUE))#install.packages("BiocManager")#BiocManager::install("ComplexHeatmap")library(ComplexHeatmap)library(circlize)#使用之前准备好的数据:expression_data,row_clusters,col_anno#注意:col_anno中已经包含了列的分组(Cluster,Gender,Age)#按自定义顺序排序矩阵(与pheatmap相同)row_order<-order(match(row_clusters,c("Cluster1","Cluster2","Cluster3")))col_order<-order(match(col_clusters,c("GroupA","GroupB")))sorted_expr<-expression_data[row_order,col_order]#创建行注释(只有cluster)row_anno<-data.frame(GeneCluster=row_clusters[row_order])#注意:行顺序已经改变,所以row_anno也要相应排序#创建列注释(已经排序,因为col_anno的行名与列名对应,且我们按col_order排序了矩阵,所以列注释也要按这个顺序)col_anno_sorted<-col_anno[col_order,,drop=FALSE]#定义颜色(与pheatmap相同)#注意:对于连续变量Age,我们使用颜色映射函数color_mapping_age<-colorRamp2(c(min(col_anno$Age),max(col_anno$Age)),c("white","brown"))ann_colors<-list(GeneCluster=c(Cluster1="red",Cluster2="blue",Cluster3="green"),Cluster=c(GroupA="orange",GroupB="purple"),Gender=c(Male="lightblue",Female="pink"),Age=color_mapping_age)#创建行注释对象ha_row<-HeatmapAnnotation(GeneCluster=row_anno$GeneCluster,which="row",col=list(GeneCluster=ann_colors$GeneCluster),show_legend=TRUE,show_annotation_name=TRUE)#创建列注释对象ha_col<-HeatmapAnnotation(df=col_anno_sorted,col=list(Cluster=ann_colors$Cluster,Gender=ann_colors$Gender,Age=ann_colors$Age),show_annotation_name=TRUE)#绘制热图#注意:我们不进行聚类,且矩阵已经排序ht<-Heatmap(sorted_expr,name="Expression",#图例名称cluster_rows=FALSE,cluster_columns=FALSE,row_order=row_order,#实际上矩阵已经排序,这里可以省略,但为了明确可以指定column_order=col_order,#同上top_annotation=ha_col,#列注释放在顶部left_annotation=ha_row,#行注释放在左侧show_row_names=FALSE,#不显示行名(基因太多)column_names_gp=gpar(fontsize=8),#列名字体大小#如果需要显示部分行名,可以使用row_labels参数,或者使用行标记(需要指定哪些行显示)#这里我们假设要显示每个cluster的前5个基因#但注意:因为我们已经按cluster排序,所以每个cluster的基因是连续的#我们可以这样选择:#row_labels=ifelse(rownames(sorted_expr)%in%selected_genes,rownames(sorted_expr),""),#但更高级的方法是使用anno_mark,但注意在RStudio中直接绘图可能有问题,建议导出为PDF#因此,我们这里先不显示行名,或者只显示少量行名(通过设置show_row_names=TRUE和调整字体大小)#另一种方法:使用row_names_gp设置字体大小,但基因太多时仍然会重叠#row_names_gp=gpar(fontsize=6)#如果显示行名,设置小字体)draw(ht)```针对标签重叠问题,如果我们希望标记每个cluster中具有代表性的基因(例如每个cluster中表达量最高的5个基因),我们可以使用`anno_mark`,但注意在RStudio中需要直接导出到文件:```r#选择每个cluster中前5个基因(这里用行索引代替,实际中可能需要根据具体数据选择)#假设我们按每个cluster的均值排序选择前5个#注意:由于矩阵已经按cluster排序,我们先按cluster分组,然后在每个组内选择前5个(按行均值)cluster_ids<-row_anno$GeneClustercluster_levels<-c("Cluster1","Cluster2","Cluster3")#初始化一个逻辑向量,标记哪些行需要显示标签selected_index<-logical(nrow(sorted_expr))for(clincluster_levels){idx<-which(cluster_ids==cl)#计算每个基因的行均值,然后取前5个(这里假设是表达量高的前5个)mean_vals<-rowMeans(sorted_expr[idx,,drop=FALSE])#按均值降序排列,取前5个top5_idx<-idx[order(mean_vals,decreasing=TRUE)[1:5]]selected_index[top5_idx]<-TRUE}selected_genes<-rownames(sorted_expr)[selected_index]selected_labels<-rownames(sorted_expr)[selected_index]#标签文本#创建行注释(包含标记)ha_row_with_mark<-ha_row#之前创建的行注释#添加一个包含标记的文本注释ha_row_mark<-rowAnnotation(mark=anno_mark(at=which(selected_index),labels=selected_labels,which="row"))#然后绘制热图时,将两个行注释(ha_row和ha_row_mark)合并ht<-Heatmap(sorted_expr,name="Expression",cluster_rows=FALSE,cluster_columns=FALSE,top_annotation=ha_col,left_annotation=ha_row,#原来的cluster颜色块注释right_annotation=ha_row_mark,#右侧添加基因标记show_row_names=FALSE,#关闭默认的行名column_names_gp=gpar(fontsize=8))#注意:在RStudio中直接绘图可能无法正确显示连接线,需要导出为PDFpdf("heatmap_with_labels.pdf",width=10,height=8)draw(ht)dev.off()#或者直接使用RStudio的导出功能(但可能仍有问题,所以建议用pdf()函数)```总结:1.自定义顺序:通过手动排序矩阵实现。2.分组注释:通过创建注释对象实现。3.标签重叠:通过选择部分基因显示(使用anno_mark)或调整字体大小解决。用户可以根据需要选择pheatmap(简单)或ComplexHeatmap(复杂且强大)方案。注意:在ComplexHeatmap中使用anno_mark时,为了避免RStudio中的显示问题,建议直接导出为PDF文件[^3]。最后,我们提供几个相关问题:§§相关问题§§1.如何在热图中添加多个行注释层?2.如何根据基因表达量自动选择每个cluster的代表基因进行标记?3.如何将热图和其他图表(如柱状图)组合在一起?4.如何优化大型热图的绘制速度?</think>以下是在RStudio中使用`pheatmap`或`ComplexHeatmap`实现自定义cluster排序的临床热图解决方案,同时保留其他分组信息(如Gender、Age)的标注:
---
### 方案一:使用pheatmap(简单实现)
```r
# 加载包
library(pheatmap)
# 1. 准备数据(示例)
set.seed(123)
expr_data <- matrix(rnorm(1000), nrow=100,
dimnames=list(paste0("Gene",1:100),
paste0("Sample",1:10)))
clinical_anno <- data.frame(
Cluster = rep(c("A","B","C"), c(3,4,3)), # 自定义cluster
Gender = sample(c("M","F"), 10, replace=TRUE),
Age = round(runif(10, 20, 80)),
row.names = colnames(expr_data)
)
# 2. 按自定义cluster顺序排序样本
custom_order <- order(match(clinical_anno$Cluster, c("A","B","C")))
sorted_data <- expr_data[, custom_order]
# 3. 设置注释颜色
anno_colors <- list(
Cluster = c(A="#1f78b4", B="#33a02c", C="#e31a1c"),
Gender = c(M="#a6cee3", F="#fb9a99"),
Age = colorRampPalette(c("white", "brown"))(10)
)
# 4. 绘制热图
pheatmap(
sorted_data,
cluster_rows = TRUE, # 基因聚类
cluster_cols = FALSE, # 禁止样本重排
annotation_col = clinical_anno[custom_order, ],
annotation_colors = anno_colors,
show_colnames = FALSE,
main = "临床样本分组热图"
)
```
**关键参数说明**:
1. `cluster_cols = FALSE`:禁止列聚类,保持自定义顺序[^4]
2. `custom_order`:通过`order(match())`实现自定义排序
3. `annotation_col`:包含Cluster、Gender、Age的分组信息
4. `annotation_colors`:为每个分组变量定义颜色映射
---
### 方案二:使用ComplexHeatmap(高级实现,解决标签重叠问题)
```r
# 安装和加载
if (!require("BiocManager")) install.packages("BiocManager")
BiocManager::install("ComplexHeatmap")
library(ComplexHeatmap)
library(circlize)
# 1. 准备数据(同方案一)
# 2. 创建列注释
ha <- HeatmapAnnotation(
df = clinical_anno,
col = list(
Cluster = c("A" = "#1f78b4", "B" = "#33a02c", "C" = "#e31a1c"),
Gender = c("M" = "#a6cee3", "F" = "#fb9a99"),
Age = colorRamp2(c(20, 80), c("white", "brown"))
)
)
# 3. 按自定义顺序排序
sample_order <- order(match(clinical_anno$Cluster, c("A","B","C")))
# 4. 绘制热图(解决标签重叠)
Heatmap(
expr_data[, sample_order],
name = "Expression",
column_order = sample_order, # 固定列顺序
top_annotation = ha,
show_column_names = FALSE,
row_names_gp = gpar(fontsize = 8), # 调整行名字体
# 可选:只显示部分基因名
row_labels = ifelse(
rownames(expr_data) %in% c("Gene1","Gene50","Gene100"),
rownames(expr_data),
""
)
) -> ht
# 5. 导出避免标签错位问题(解决RStudio显示问题)
pdf("clinical_heatmap.pdf", width=10, height=8)
draw(ht)
dev.off()
```
**关键优势**:
1. `column_order`:直接指定列顺序[^2]
2. `row_labels`:选择性显示基因名,解决重叠问题[^1]
3. `colorRamp2`:为连续变量(Age)创建平滑颜色梯度
4. PDF导出:避免RStudio中`anno_mark()`的显示问题[^3]
---
### 分组信息整合技巧
1. **多级注释**:
```r
# ComplexHeatmap中添加多个注释层
ha <- HeatmapAnnotation(
Cluster = clinical_anno$Cluster,
Gender = clinical_anno$Gender,
Age = clinical_anno$Age,
col = list(...) # 单独定义每个变量的颜色
)
```
2. **分组间隔线**(pheatmap):
```r
pheatmap(...,
gaps_col = cumsum(table(clinical_anno$Cluster))[-3]
)
```
3. **大型数据集优化**:
```r
# 只显示cluster边界基因
boundary_genes <- c(1, which(diff(as.numeric(factor(clinical_anno$Cluster))) != 0)+1)
row_labels <- ifelse(1:nrow(expr_data) %in% boundary_genes,
rownames(expr_data), "")
```
---
### 相关问题
1. 如何为热图中的连续变量(如Age)创建自定义颜色梯度?
2. 当样本量过大时,如何优化热图的渲染速度?
3. 如何在ComplexHeatmap中添加基因功能通路注释?
4. 如何将热图与生存分析结果整合展示?
5. 导出热图时如何保持分组注释与主热图的对应关系?
阅读全文
相关推荐
