提问者:小点点

ggplot在EventResponsive()中无法正常工作


我浪费了几个小时来找出为什么我的绘图在我更改输入时自动更新自己,而它本应该等待运行按钮,但它只是忽略了这一步,我最终发现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)

如果你运行这个,你会注意到,在第一次运行后,ggplod不再关心运行按钮,它会在你更改输入时不断更新!!然而,如果您使用简单的基本绘图函数(我在代码中添加了注释),就不会有任何问题,而且工作正常!可悲的是,我需要在我的应用程序,因为基本情节是丑陋的。我看到了一些建议,用于解决这个问题,但我不知道在哪里应该把隔离()来解决我的问题,也没有意义使用隔离()时,基本情节函数工作正常,没有它,它是ggploit,使问题。如有任何解释,将不胜感激。


共2个答案

匿名用户

如果您遵循ggplot传递列名的首选方法,即使用,似乎效果不错。数据

library(ggplot2)
library(shiny)

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(.data[[input$outvar]], pred)) +
      labs(x = "Observed", y = "Predicted") +
      geom_point() +
      theme_bw()
  })
  
  
  output$plot <- renderPlot({
    plt()
  })
}

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

匿名用户

我认为问题是ggplod在懒惰地处理事情。如果您对代码做了一次更改,以预拉df()输入$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
    dat <- df()
    outv <- input$outvar
    ggplot(dat, aes(dat[, outv], pred)) +
      labs(x = "Observed", y = "Predicted") +
      geom_point() +
      theme_bw()

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

问题是ggplod以某种方式在内部保留了一些反应性。

(我把赋值放在datoutv的前面,只是为了演示。更明智的做法可能是在eventReactive块中首先分配它们,并对所有内容使用dat,只是为了代码的一致性(其他代码都没有在懒惰原则上运行)。