如何在Shiny中按多条件调整y轴高度适配geom_text标签
问题描述
开发Shiny应用时遇到需求:勾选p-values选项后,仅当当前分类下最高柱子(对应new_est最大值)的Sig字段不为NA时,才扩展y轴避免p值星号被截断;若最高柱子的Sig为NA,即使勾选p值也不扩展y轴。当前代码是只要勾选p值就扩展y轴,不符合需求。
解决方案
修改server中renderPlot的逻辑即可实现,步骤如下:
- 先获取当前分类的完整数据集
将原来单独提取各列的代码,改为先保存当前分类的完整数据,方便后续判断:
output$plot_overall <- renderPlot({ # 先获取当前分类的完整数据 current_data <- fun_select_cat(table_2, input$cat) # 从完整数据中提取需要的列 control_y <- current_data %>% pull(Control) Sig_height_y <- current_data %>% pull(Sig_height) Sig_y <- current_data %>% pull(Sig) new_est_y <- current_data %>% pull(new_est)
- 判断是否满足y轴扩展条件
添加逻辑判断,同时检查两个条件:
# 获取最高new_est对应的Sig值,判断是否非NA max_sig_valid <- current_data %>% filter(new_est == max(new_est)) %>% pull(Sig) %>% {!is.na(.)} # 合并条件:勾选p值 且 最高柱子的Sig非NA need_expand_y <- input$p_values && max_sig_valid
- 替换原y轴扩展语句
将原来的{if(input$p_values) expand_limits(y= c(0, new_est_y *1.05))}替换为:
current_data %>% ggplot(aes(x = Treatment, y = new_est, fill = Treatment)) + # ... 其他原有图层 ... {if(need_expand_y) expand_limits(y= c(0, max(new_est_y) *1.05))} + # ... 其他原有图层 ...
完整修改后的server代码
server <- function(input, output, session) { observeEvent(input$Explain_p_values, {showModal(modalDialog(p_value_text))}) output$plot_overall <- renderPlot({ # 获取当前分类的完整数据 current_data <- fun_select_cat(table_2, input$cat) control_y <- current_data %>% pull(Control) Sig_height_y <- current_data %>% pull(Sig_height) Sig_y <- current_data %>% pull(Sig) new_est_y <- current_data %>% pull(new_est) # 判断是否需要扩展y轴 max_sig_valid <- current_data %>% filter(new_est == max(new_est)) %>% pull(Sig) %>% {!is.na(.)} need_expand_y <- input$p_values && max_sig_valid current_data %>% ggplot(aes(x = Treatment, y = new_est, fill = Treatment)) + geom_col() + scale_fill_manual(values = cbPalette) + guides(fill = FALSE) + scale_y_continuous(labels = label_comma(), expand = c(0,0)) + theme_classic() + scale_x_discrete(drop=FALSE) + theme(plot.title = element_text(hjust=0.5, size=14,face="bold"), axis.text=element_text(size=12)) + {if(input$p_values) geom_text(aes(label = Sig_y), y = Sig_height_y)} + {if(need_expand_y) expand_limits(y= c(0, max(new_est_y) *1.05))} + {if(input$control_mean) annotate("text", x = 3.6, y = 1.078 * control_y, label = "Control\nmean", colour = "#CC79A7", fontface =2, size = 4.5)} + {if(input$control_mean)expand_limits(x= c(1, length(levels(table_2$Treatment)) + 0.75))} + {if(input$control_mean) geom_hline(aes(yintercept = Control), linetype='dashed', col = '#CC79A7', size = 1.5)} + if(input$cat %in% c("Number of Enterprises", "Assets") ) {labs(title= input$cat, x = NULL, y = NULL) } else{labs(title = paste(input$cat, "(USD) for the last 30 days", sep =" "), x = NULL, y = NULL)} }) }
内容的提问来源于stack exchange,提问作者hks
相关产品推荐
相关产品推荐

