ggplot嵌套分面使用reorder_within时去除分面标签后缀求助
问题原因
tidytext::reorder_within() 为了实现分面内独立排序,会给因子值拼接___+分面组名的后缀,配套的scale_x_reordered()只会清洗坐标轴刻度的后缀,不会处理ggh4x::facet_nested()生成的嵌套分面条带标签。你之前直接传入自定义labeller函数报错,是因为嵌套分面要求labeller必须通过labeller()封装为按分面变量匹配的格式,不能直接传入全局处理函数。
解决方案
方案1:适配嵌套分面的标签清洗(改动最小)
只需要修改facet_nested()的labeller参数,单独对Company列的条带标签做后缀清洗,Level列保持原有标签格式即可,不需要改动其他绘图逻辑:
facet_nested(. ~ Level + Company, scales = "free_x", labeller = labeller( # 匹配___开头到末尾的所有内容,直接删除 Company = function(x) gsub("___.*$", "", x), # 其余分面变量沿用原来的自动换行逻辑 .default = label_wrap_gen(width = 15, multi_line = TRUE) ))
这个写法不会触发你之前遇到的参数格式报错,清洗逻辑精准,不会误删标签本身带的下划线字符。
方案2:提前手动排序(无后缀问题,适配性更强)
如果不想处理后缀,可以完全绕开reorder_within的逻辑,在数据预处理阶段就完成每个Level分组内的Company排序,从根源上避免带后缀的因子生成:
library(ggplot2) library(ggh4x) library(dplyr) Col = c("Flag_1" = "#0067A8", "Flag_2" = "#FFDC00") data %>% mutate( Level = as.factor(Level), YEAR = as.factor(YEAR) ) %>% group_by(Level) %>% # 按每个Level下2020年的Rank值升序排列Company,直接设置因子水平 mutate(Company = factor( Company, levels = Company[YEAR == 2020][order(Rank[YEAR == 2020])] )) %>% ungroup() %>% # 绘图 ggplot(aes(x = YEAR, y = Result, fill = Colour_flag)) + facet_nested(. ~ Level + Company, scales = "free_x", labeller = label_wrap_gen(width = 15, multi_line = TRUE)) + # 不需要再调用scale_x_reordered() geom_bar(stat = "identity") + geom_text(aes(y = Result, label = round(Result, 0)), position = position_dodge(0.9), hjust = 1.5, vjust = 0.5, angle = 90, size = 3.5) + scale_fill_manual(values = Col) + theme_minimal() + theme( axis.title.x = element_blank(), axis.title.y = element_blank(), axis.text.x = element_text(angle = 90, hjust = 0, vjust = 0.5, size = 10), strip.text.x = element_text(size = 11), axis.text.y = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), legend.position = 'none', panel.spacing = unit(c(0.5,0.5,0.5,0.5,30, 0.5,0.5,0.5,0.5), "pt") )
这个方案排序逻辑完全可控,后续如果需要调整排序规则(比如按多年均值排序、倒序排列),只需要修改因子水平设置的那行代码即可,不会出现标签适配问题。
内容的提问来源于stack exchange,提问作者Keelin
相关产品推荐
相关产品推荐

