R语言ggplot柱状图原生运行正常但移植到Shiny后分面与标签缺失
问题根源
aes_()传参逻辑错误:原Shiny代码中aes_(x = 'BusinessTravel', group = ~Attrition)直接将单引号包裹的字符串作为x轴映射值,aes_()会把这个字符串识别为固定常量,而非数据框中的列名,最终所有样本被归为同一x类别,完全破坏了占比计算和分面展示逻辑- 映射错误带来的连锁反应:所有样本归为同一x类别后,每个分面内的占比计算结果恒为1,geom_text设置的垂直位置(vjust=2)超出y轴显示范围,进一步导致文本标签完全不可见
- 原生R环境下的代码使用公式形式传参(
~BusinessTravel、~Attrition),aes_()可以正确识别列引用,因此展示正常
修复方案
根据x轴字段的使用场景调整代码:
场景1:x轴为硬编码列名(如固定使用BusinessTravel列)
aes_() 本为动态传参场景设计,硬编码列名时完全可以直接使用普通aes()映射;同时将旧版弃用的..prop..、..x..变量替换为兼容新版ggplot2的after_stat()写法,避免版本兼容问题。
场景2:x轴为动态选择的列(如通过input下拉框选择字段)
使用rlang动态语法将输入的列名字符串转为可识别的列引用,杜绝常量映射错误。
修复后的Shiny代码示例:
output$cat_vs_cat_chart2 <- renderPlot({ # 硬编码列的写法 data() %>% ggplot(aes(x = BusinessTravel, group = Attrition)) + geom_bar(aes(y = after_stat(prop), fill = factor(after_stat(x))), stat = "count", alpha = 0.7) + geom_text(aes(label = scales::percent(after_stat(prop), accuracy = 0.1), y = after_stat(prop)), stat = "count", vjust = 1.5) + facet_grid(~Attrition) + theme_minimal() + theme(legend.position = "none", plot.title = element_text(hjust = 0.5)) + ggtitle("Attrition") # 动态选择列的写法(替换上述aes映射即可) # selected_x <- sym(input$cat_compare) # data() %>% # ggplot(aes(x = !!selected_x, group = Attrition)) + # 后续图层逻辑保持一致 })
内容的提问来源于stack exchange,提问作者duy ngọc
相关产品推荐
相关产品推荐

