如何在ggplot2中自定义动态生成的X轴标签顺序?
在ggplot2中自定义动态生成的X轴标签顺序
核心思路
解决动态生成带样本数的X轴标签排序问题,关键是锚定原Level列的自定义顺序,以此为依据设置新生成的Level_N标签的因子水平,让ggplot按需求渲染X轴。
方法一:基于原Level顺序设置新标签的因子水平
先将原Level转换为指定顺序的因子,分组生成带样本数的标签后,提取对应顺序的标签列表作为Level_N的因子水平:
library(tidyverse) set.seed(1) df = data.frame(SUBJID = 1001:1010, Level = sample(c("Normal", "Mild", "Moderate", "Severe"), 10, replace = T), Value = runif(10, min = 200, max = 500)) # 1. 定义原Level的固定顺序 df$Level = factor(df$Level, levels = c("Normal", "Mild", "Moderate", "Severe")) df %>% group_by(Level) %>% mutate( SUBJN = n_distinct(SUBJID), Level_N = paste(Level, "(N=", SUBJN, ")") ) %>% # 2. 按原Level顺序提取对应Level_N,设置为因子水平 mutate(Level_N = factor(Level_N, levels = unique(Level_N[order(Level)]))) %>% ggplot(aes(Level_N, Value)) + geom_boxplot()
unique(Level_N[order(Level)])会按照Level的自定义顺序提取对应标签,确保Level_N的因子水平完全符合需求。
方法二:使用fct_reorder正确排序
若想用fct_reorder,需先将原Level设为有序因子,且排序前取消分组(避免分组内排序无效):
library(tidyverse) set.seed(1) df = data.frame(SUBJID = 1001:1010, Level = sample(c("Normal", "Mild", "Moderate", "Severe"), 10, replace = T), Value = runif(10, min = 200, max = 500)) df %>% # 定义原Level的固定顺序 mutate(Level = factor(Level, levels = c("Normal", "Mild", "Moderate", "Severe"))) %>% group_by(Level) %>% mutate( SUBJN = n_distinct(SUBJID), Level_N = paste(Level, "(N=", SUBJN, ")") ) %>% ungroup() %>% # 必须取消分组,否则fct_reorder无法全局排序 # 基于原Level的数值(对应自定义顺序)重新排列Level_N mutate(Level_N = fct_reorder(Level_N, as.numeric(Level))) %>% ggplot(aes(Level_N, Value)) + geom_boxplot()
之前尝试无效的原因
你之前的代码在group_by后直接使用fct_reorder,此时每个分组内的as.numeric(Level)为单一值,无法实现全局排序;同时未将原Level设为指定顺序的因子,as.numeric(Level)会默认按字母顺序生成数值,导致排序不符合预期。
内容的提问来源于stack exchange,提问作者Dylan Li
相关产品推荐
相关产品推荐

