如何在ggplot分组条形图中按规则调整每组内样本的排序?
分组条形图的组内样本排序解决方案
一、基础分组内排序(解决初始bacteria组顺序问题)
你当前的问题是仅按type列排序样本,未在每个type分组内对sample做自定义排序。要实现先按type分组,组内按自然数字顺序排序,可按以下步骤操作:
步骤1:分组并组内排序
使用dplyr工具链(或base R)先对每个type组内的sample进行自然排序,再合并得到全局样本顺序:
library(dplyr) # 分组后组内自然排序,提取排序后的样本向量 sorted_samples <- mydf %>% group_by(type) %>% arrange(gtools::mixedorder(sample)) %>% pull(sample) %>% unique() # 设置sample的因子水平为排序后的向量 mydf$sample <- factor(mydf$sample, levels = sorted_samples)
若不用dplyr,base R实现方式:
# 按type拆分数据,每组内用mixedorder排序后合并 sorted_list <- lapply(split(mydf, mydf$type), function(x) { x[gtools::mixedorder(x$sample), "sample"] }) sorted_samples <- unlist(sorted_list) mydf$sample <- factor(mydf$sample, levels = sorted_samples)
步骤2:绘制条形图
此时绘图,virus组保持原有顺序,bacteria组会按A56/A110/A1230的自然顺序排列:
ggplot(mydf, aes(x=sample, y=expr, fill=type)) + geom_bar(stat="identity")
二、复杂命名样本的自然排序(处理phage样本)
对于含连字符、多段数字的样本名(如T1382-1、T289-3),gtools::mixedorder或stringr::str_sort(需指定numeric = TRUE)均可实现自然排序,核心是在分组内应用排序规则,再统一设置因子水平。
示例:合并phage数据并排序
先构造phage数据并合并到原数据框:
# 创建phage数据框 phage_df <- data.frame( sample = c( "T2505", "T815", "T3046", "T943", "T518", "T1382-2", "T413", "T2307", "T1382-1", "T289-3"), type = "phage", expr = rnorm(10, mean = 5) # 随机生成表达值 ) # 合并数据 mydf_full <- rbind(mydf, phage_df) # 指定分组显示顺序 mydf_full$type <- factor(mydf_full$type, levels = c("virus", "bacteria", "phage"))
分组内自然排序并设置因子水平
# 分组内自然排序,提取全局样本顺序 sorted_samples_full <- mydf_full %>% group_by(type) %>% arrange(stringr::str_sort(sample, numeric = TRUE)) %>% # 或用gtools::mixedorder(sample) pull(sample) %>% unique() # 设置sample因子水平 mydf_full$sample <- factor(mydf_full$sample, levels = sorted_samples_full) # 绘制条形图(旋转x轴标签避免重叠) ggplot(mydf_full, aes(x=sample, y=expr, fill=type)) + geom_bar(stat="identity") + theme(axis.text.x = element_text(angle = 45, hjust = 1))
关键说明
- 必须先分组,再在组内应用排序规则,最后合并得到全局样本顺序,才能保证分组内排序正确,同时分组间顺序符合指定的
type因子水平。 stringr::str_sort(sample, numeric = TRUE)与gtools::mixedorder都能处理含数字、特殊字符的自然排序,效果一致,可根据习惯选择。
内容的提问来源于stack exchange,提问作者Fabrice
相关产品推荐
相关产品推荐

