scale_x_discrete为何重复数据?ggplot2轴标签异常问题
ggplot2中scale_x_discrete的x轴标签出现循环复用问题
问题描述
构建数据并添加排序用的gruppen_id后,绘制条形图时整体显示正常,但通过scale_x_discrete设置的x轴标签中,“n (total)”的值出现循环复用(recycle)错误。相关代码如下:
数据构建与排序代码
library(tidyverse) library(ggplot2) library(ggtext) df <- structure( list( variable = c( "var1", "var1", "var1", "var2", "var2", "var2", "var3", "var3", "var3", "var4", "var4", "var4" ), gruppe = structure( c(1L, 7L, 16L, 1L, 7L, 16L, 1L, 7L, 16L, 1L, 7L, 16L), levels = c( "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLL", "MMMM", "NNNN", "OOOO", "PPPP GGGG" ), class = "factor" ), auspraegung = rep("lorem ipsum", 12), n = c(148L, 32L, 89L, 135L, 31L, 93L, 123L, 28L, 76L, 115L, 26L, 67L), prozent = c(88.1, 84.2, 85, 81.3, 81.6, 89, 74.1, 73.7, 72, 69.7, 68.4, 65), gruppen_variablen_summe = c(168L, 38L, 105L, 166L, 38L, 105L, 166L, 38L, 105L, 165L, 38L, 103L), auspr_n = c( "88.1% \nn = 148", "84.2% \nn = 32", "85% \nn = 89", "81.3% \nn = 135", "81.6% \nn = 31", "89% \nn = 93", "74.1% \nn = 123", "73.7% \nn = 28", "72% \nn = 76", "69.7% \nn = 115", "68.4% \nn = 26", "65% \nn = 67" ), gruppe_n = c( "AAAA \nn = 168", "GGGG \nn = 38", "PPPP GGGG \nn = 105", "AAAA \nn = 166", "GGGG \nn = 38", "PPPP GGGG \nn = 105", "AAAA \nn = 166", "GGGG \nn = 38", "PPPP GGGG \nn = 105", "AAAA \nn = 165", "GGGG \nn = 38", "PPPP GGGG \nn = 103" ) ), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA,-12L), groups = structure( list( variable = c( "var1", "var1", "var1", "var2", "var2", "var2", "var3", "var3", "var3", "var4", "var4", "var4" ), gruppe = structure( c(1L,7L,16L,1L,7L,16L,1L,7L,16L,1L,7L,16L), levels = c( "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLL", "MMMM", "NNNN", "OOOO", "PPPP GGGG" ), class = "factor" ), .rows = structure( list(1L,2L,3L,4L,5L,6L,7L,8L,9L,10L,11L,12L), ptype = integer(0), class = c("vctrs_list_of","vctrs_vctr","list") ) ), class = c("tbl_df","tbl","data.frame"), row.names = c(NA,-12L), .drop = TRUE ) ) varlabels <- c( "var1" = "Text var 1", "var2" = "Text var 2", "var3" = "Text var 3", "var4" = "Text var 4" ) # 添加分组ID用于排序 df$gruppen_id <- rep(c(2,1,3), times = 4)
原因分析
出现循环复用的核心原因是传入scale_x_discrete(labels = ...)的标签向量长度,与x轴实际的离散刻度数量不匹配:
- 你的x轴对应的离散变量(
gruppe)只有3个唯一级别:AAAA、GGGG、PPPP GGGG。 - 如果错误地传入长度为12的向量(比如直接用
df$gruppe_n),R会触发向量循环机制——重复短向量直到匹配长向量的长度,导致标签被循环复用,显示错误的“n (total)”值。
解决方法
1. 生成匹配长度的标签向量
先提取每个分组对应的唯一总样本量,生成与x轴刻度数量一致的标签:
# 按排序ID提取每个分组的唯一标签 group_labels <- df %>% distinct(gruppe, gruppen_variablen_summe, gruppen_id) %>% arrange(gruppen_id) %>% # 按指定顺序排序 mutate(label = paste0(gruppe, "\nn (total) = ", gruppen_variablen_summe)) %>% pull(label)
2. 在绘图中使用正确的标签
在scale_x_discrete中传入生成的标签向量,同时用reorder确保条形按指定顺序排列:
ggplot(df, aes(x = reorder(gruppe, gruppen_id), y = prozent, fill = gruppe)) + geom_col(position = "dodge") + # 根据需求调整位置 scale_x_discrete(labels = group_labels) + facet_wrap(~variable, labeller = labeller(variable = varlabels)) + # 可选:添加变量标签 labs(x = "分组", y = "百分比") + theme_minimal()
这样就能保证每个x轴刻度对应正确的“n (total)”值,不会出现循环复用的问题。
内容的提问来源于stack exchange,提问作者Dierforth
相关产品推荐
相关产品推荐

