基于多selectInput选择在Shiny中渲染动态数量图表
问题解决:Shiny动态图表重复显示相同数据
问题根源
你的代码中,虽然用local()创建了局部变量my_i,但在gvisColumnChart的yvar参数里仍使用了循环变量i,而非局部变量my_i。由于Shiny反应式环境的特性,循环结束后i会固定为最后一个遍历的变量值,导致所有图表都绑定同一个变量生成,最终显示相同数据。
修复后的完整代码
library(googleVis) mtcars$Car.Name <- row.names(mtcars) ui <- fluidPage( headerPanel("Dynamic number of plots"), sidebarPanel( selectInput(inputId = "chooseVar", label = "Choose Cut Variable:", choices = colnames(mtcars)[-length(colnames(mtcars))], multiple = T), selectInput(inputId = "chooseCar", label = "Choose Car :", choices = row.names(mtcars), multiple = T) ), mainPanel( # 动态图表的UI容器 uiOutput("plots") ) ) server <- function(input, output) { varList <- reactive(input$chooseVar ) # 动态生成图表对应的UI元素 output$plots <- renderUI({ plot_output_list <- lapply(varList() , function(i) { plotname <- paste0("plot_", i) htmlOutput(plotname) }) tagList(plot_output_list) }) # 为每个变量创建对应的图表输出 for (i in colnames(mtcars)[-length(colnames(mtcars))]) { local({ my_i <- i plotname <- paste0("plot_", my_i) output[[plotname]] <- renderGvis({ data <- mtcars[row.names(mtcars) %in% input$chooseCar, ] if(nrow(data) > 0){ gvisColumnChart( data, xvar='Car.Name', yvar= my_i # 改用局部变量my_i绑定当前循环值 ) } else { NULL } }) }) } } shinyApp(ui = ui, server = server)
额外优化建议
- 用
nrow(data)替代dim(data)[1],代码更简洁易读。 - 若希望仅为用户选中的变量生成图表(避免预先生成未被选择的输出),可将输出生成逻辑改为响应式遍历选中变量,更高效:
# 替代原for循环的优化写法 observe({ lapply(varList(), function(my_i) { plotname <- paste0("plot_", my_i) output[[plotname]] <- renderGvis({ data <- mtcars[row.names(mtcars) %in% input$chooseCar, ] if(nrow(data) > 0){ gvisColumnChart(data, xvar='Car.Name', yvar= my_i) } else { NULL } }) }) })
内容的提问来源于stack exchange,提问作者lrclark
相关产品推荐
相关产品推荐

