ggplot 在闪亮的 eventReactive() 内无法正常工作

时间:2021-03-28 06:46:52

标签: r ggplot2 shiny

我浪费了几个小时来找出为什么当我更改输入时我的绘图会自动更新,而它应该等待运行按钮,但它只是忽略了这一步,我最终找到了< strong>ggplot 作为麻烦制造者!!!这是我的最小代码:

library(ggplot2)
library(tidyverse)

varnames <- names(cars)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fluidRow(
        column(
          width = 12,

          # Variables Inputs:
          varSelectInput("variables", "Select Input Variables", cars, multiple = TRUE),
          selectizeInput("outvar", "Select Output Variable", choices = varnames, "speed", multiple = F),

          # Run Button
          actionButton(inputId = "run", label = "Run")
        )
      )
    ),

    # Main panel for displaying outputs ----
    mainPanel(
      plotOutput("plot")
    )
  )
)

server <- function(input, output, session) {
  
  df <- reactive({
    cars %>% dplyr::select(!!!input$variables, input$outvar)
  })


  plt <- eventReactive(input$run, {
    
    #Just creating lm formula
    current_formula <- paste0(input$outvar, " ~ ", paste0(input$variables, collapse = " + "))
    current_formula <- as.formula(current_formula)
    #Fitting lm
    fit <- lm(current_formula, data = df())
    pred <- predict(fit, newdata = df())

    #Plotting
    ggplot(df(), aes(df()[, input$outvar], pred)) +
      labs(x = "Observed", y = "Predicted") +
      geom_point() +
      theme_bw()

     #plot(df()[, input$outvar], pred)       #This one works fine!!!!
  })


  output$plot <- renderPlot({
     plt()
  })
}

# Run the application
shinyApp(ui = ui, server = server)

如果你运行这个,你会注意到 ggplot 在第一次运行后不再关心 Run 按钮,它会随着你改变输入而不断更新!!但是,如果您使用简单的基本 plot 函数(我在代码中添加了注释),就不会有任何问题,而且效果很好!可悲的是,我的应用程序中需要 ggplot,因为基本图很难看。我看到了使用isolate()来解决这个问题的建议,但我不知道应该把isolate()放在哪里来解决我的问题,当基本绘图功能没有它时使用isolate()也没有意义,并且这是造成问题的ggplot。任何解释将不胜感激。

1 个答案:

答案 0 :(得分:0)

问题是 ggplot 美学是惰性评估的。您真的想将符号放入 aes() 而不是反应数据值。将绘图代码更改为

ggplot(df(), aes(.data[[input$outvar]], pred)) +
  labs(x = "Observed", y = "Predicted") +
  geom_point() +
  theme_bw()

使用 ggplot,您可以使用 .data 代词访问当前数据源,而不是再次触发反应式 df() 对象。