用于生成图的反应式和事件反​​应式的组合

Combination of reactive and eventReactive for generating a plot

概览: 我正在使用反应组件根据用户输入动态更新数据集。这没有任何问题。

附加要求:我只想在单击按钮时为绘图着色。 当前设置:点击'Color'按钮后,即使更改数据集,颜色仍然存在。

我在 observeEvent 块中定义了相同的输出元素,以覆盖 server.out 中定义的默认元素。但是,此覆盖是永久性的。

library(shiny)
shinyApp(ui = fluidPage(
  sidebarPanel(
    selectInput(inputId = "dropdown", label = "Select data set:",
                choices = c("iris", "mtcars"), selected = "iris")
  ),

  mainPanel(fluidPage(
    fluidRow(plotOutput("plot"),
             actionButton("color", "Color"))
  ))
), server = function(input, output) {
  get_data <- reactive({
    if(input$dropdown == "iris") {
      return(list(dat = iris, x = "Sepal.Length", color = "Species"))
    } else {
      return(list(dat = mtcars, x = "mpg", color = "cyl"))
    }
  })
  output$plot <- renderPlot({
    dat <- get_data()
    return(plot(dat$dat[, dat$x]))
  })

  observeEvent(input$color, {
    output$plot <- renderPlot({
      dat <- get_data()
      return(plot(dat$dat[, dat$x], col = dat$dat[, dat$color]))
    })
  })
})

实际结果: 即使我更改了数据集,每次单击 "Color" 按钮都会出现颜色。 预期结果: 单击当前数据集的 "Color" 后应该会出现颜色。一旦我更改数据集,它就不应该出现。只有当我再次单击 "Color" 按钮时,它才会重新出现。

您似乎想要跟踪状态。你真的不能 "un-click" 一个按钮,所以最好只存储一个反应值来指示你是否想要颜色,并且你可以在数据集更改时重置它。这里有这样一个服务器函数

function(input, output) {

  showColor <- reactiveVal(FALSE)

  get_data <- reactive({
    if(input$dropdown == "iris") {
      return(list(dat = iris, x = "Sepal.Length", color = "Species"))
    } else {
      return(list(dat = mtcars, x = "mpg", color = "cyl"))
    }
  })
  output$plot <- renderPlot({
    dat <- get_data()
    if (showColor()) {
      plot(dat$dat[, dat$x], col = dat$dat[, dat$color])
    } else {
      plot(dat$dat[, dat$x])
    }
  })
  observeEvent(input$dropdown, {
    showColor(FALSE)
  })
  observeEvent(input$color, {
    showColor(TRUE)
  })
}

您看到我们添加了 showColor <- reactiveVal(FALSE) 部分,因此默认情况下它不会显示颜色,并在下拉列表更改时将其重置为 FALSE。当您按下 "color" 按钮时,我们将其设置为 TRUE

您可以显式观察由 input$dropdown:

触发的事件
function(input, output) {
  get_data <- reactive({
    if(input$dropdown == "iris") {
      return(list(dat = iris, x = "Sepal.Length", color = "Species"))
    } else {
      return(list(dat = mtcars, x = "mpg", color = "cyl"))
    }
  })
  observeEvent(input$dropdown, {
    output$plot <- renderPlot({
      dat <- get_data()
      return(plot(dat$dat[, dat$x]))
    })  
  })

  observeEvent(input$color, {
    output$plot <- renderPlot({
      dat <- get_data()
      return(plot(dat$dat[, dat$x], col = dat$dat[, dat$color]))
    })
  })
}