当变量超过阈值时,触发一个闪亮的事件

时间:2015-11-26 19:08:40

标签: r events shiny reactive-programming

我有一个连续变量(传单地图上的缩放),我只想在此变量超过给定阈值时激活某些动作(多边形绘制)(仅在给定的缩放级别之后)。

这是一个类似的 - 但更简单,更容易重现 - 玩具问题:

ui <- bootstrapPage(
  sliderInput("slider", label='a number', min=100, max=400, value = 150),
  plotOutput("plot")
)

server <- function(input, output, session) {
  observeEvent(input$slider > 200, {
    output$plot <- renderPlot(plot(rnorm(10000), rnorm(10000)))
  })
}

shinyApp(ui, server)

问题是,由于Shiny的反应系统,情节(在玩具问题中)或地图(在实际问题中)不断更新,即使我想要它们只有在阈值传递时才会更新,无论是哪个方向。

我尝试使用observeEventeventReactivereactiveValues等与if ... else声明混合的结构。但似乎无论何时更新输入,它都会触发整个事件链,无论因变量是否已更改。在玩具问题中,当input$slider > 200TRUE转到input$slider时,100保持101无关紧要,无论如何都会触发绘图。

请告诉我,我错了!

2 个答案:

答案 0 :(得分:3)

您可以使用常规observeEvent()而不是使用observe(),并将条件用于if语句,如果条件失败则只使用return()

这样的东西
observe({
    if (input$slider <= 200) return()
    ...
})

编辑:在评论中,您想以某种方式跟踪最后一个值。这是你如何做到这一点。

library(shiny)
ui <- fluidPage(
  sliderInput("slider", "Slider", 1, 500, 100)
)
server <- function(input, output, session) {
  values <- reactiveValues(last = 0)
  observe({
    if (input$slider <= 200 & values$last > 200) {
      cat("check!")
    }
    values$last <- input$slider
  })
}
shinyApp(ui = ui, server = server)

答案 1 :(得分:0)

因此,受@ daattali和我们讨论的启发,一种可能的解决方案是使用reactiveValue来存储滑块的最后一个值,以便测试在任一方向上传递阈值的时间。测试本身在observe函数中进行:

ui <- bootstrapPage(
  sliderInput("slider", label='a number', min=100, max=400, value = 150),
  plotOutput("plot")
)

server <- function(input, output, session) {
  output$plot <- renderPlot(plot(rnorm(10000), rnorm(10000)))
  last        <- reactiveValues(value = 0)
  observe({
    if ((input$slider <= 200 & last$value > 200)|(input$slider > 200 & last$value <= 200)) {
      output$plot <- renderPlot(plot(rnorm(10000), rnorm(10000)))
    }
    last$value <- input$slider
  })
}

shinyApp(ui, server)

使用此解决方案,只有在任一方向上传递阈值(滑块上的200)时才能正确更新。