在R中为二元分类变量绘制热力图并按行排序的方法求助
解决方案
下面提供两种可实现需求的方法:按每行yes数量降序排列观测ID,并用两种颜色区分yes/no类别。
方法一:使用ggplot2(灵活自定义样式)
1. 数据预处理
先加载依赖包,将分类变量转为二进制格式以计数,再按每行yes的数量排序:
library(dplyr) library(tidyr) library(ggplot2) # 复制原数据避免修改原始对象 df_processed <- df1 %>% # 将yes/no转为1/0,便于统计数量 mutate(across(starts_with("var"), ~ifelse(.x == "yes", 1, 0))) %>% # 计算每行yes的总数 mutate(yes_count = rowSums(select(., starts_with("var")))) %>% # 按yes_count降序排序 arrange(desc(yes_count)) %>% # 将ID转为因子,确保绘图时按排序后的顺序展示 mutate(ID = factor(ID, levels = ID)) # 转为长格式,适配ggplot绘图逻辑 df_long <- df_processed %>% select(-yes_count) %>% pivot_longer(cols = starts_with("var"), names_to = "variable", values_to = "value") %>% # 把数值转回yes/no标签 mutate(value = ifelse(value == 1, "yes", "no"))
2. 绘制热力图
ggplot(df_long, aes(x = variable, y = ID)) + geom_tile(aes(fill = value), color = "white") + # 白色边框区分单元格 scale_fill_manual(values = c("yes" = "#2ecc71", "no" = "#e74c3c")) + # 自定义yes/no的颜色 labs(x = "变量", y = "观测ID", fill = "类别") + theme_minimal() + theme(axis.text.y = element_text(size = 10), axis.text.x = element_text(size = 10))
方法二:使用pheatmap(简洁的热力图工具)
1. 整理数值矩阵
library(pheatmap) # 提取变量列并转为矩阵,将ID设为行名 df_matrix <- df1 %>% column_to_rownames("ID") %>% mutate(across(everything(), ~ifelse(.x == "yes", 1, 0))) %>% as.matrix() # 计算每行yes的数量,生成自定义排序的行索引 yes_counts <- rowSums(df_matrix) row_order <- names(sort(yes_counts, decreasing = TRUE))
2. 绘制热力图
pheatmap(df_matrix[row_order, ], color = c("#e74c3c", "#2ecc71"), # 对应no和yes的颜色 cluster_rows = FALSE, # 关闭自动聚类,使用自定义排序 cluster_cols = FALSE, # 保持原变量顺序 legend_labels = c("no", "yes"), main = "二元分类变量热力图", border_color = "white")
补充说明
- base R的
heatmap()函数更偏向数值矩阵的聚类展示,对分类变量的自定义支持有限,因此推荐使用上述两种工具; - 你可以根据喜好修改代码中的颜色十六进制码,调整热力图的视觉风格。
内容的提问来源于stack exchange,提问作者SteveMcManaman
相关产品推荐
相关产品推荐

