Shiny:observeEvent和eventReactive有什么区别?

时间:2015-11-04 10:45:50

标签: r shiny reactive-programming shiny-server

我现在几次阅读有关反应式编程的Shiny文档,但我无法正确理解observeEventeventReactive之间的区别。

文档说:

  

每当您想要执行操作以响应事件时,请使用observeEvent。 (请注意,“重新计算值”通常不会被视为执行操作 - 请参阅eventReactive。)

     

...

     

使用eventReactive创建一个仅响应事件而更新的计算值。这就像一个普通的反应式表达式,除了它忽略了来自其反应依赖的所有常见的失效;

在我试过的所有情况下,我发现使用observeEventeventReactive之间没有区别(无论我使用哪种功能,代码都能正常工作,对性能没有明显影响)。

你能帮我弄清楚两者之间的真正区别吗?理想情况下,我想举几个例子说明它们何时可以互换,一个observeEvent可以工作但不eventReactive,反之亦然。

5 个答案:

答案 0 :(得分:29)

这就像observereactive之间的区别。一个是在某个反应变量被“触发”并且意图产生副作用(observeEvent)时运行,而另一个反应返回一个反应值并且意味着用作变量({{1} })。即使在这些函数的文档中,前者显示时没有分配给变量(因为它只是产生副作用),而后者显示为分配给变量并在以后使用。

答案 1 :(得分:23)

正如@daatali所说,这两个函数用于不同目的。

ui <- shinyUI(pageWithSidebar(
  headerPanel("eventReactive and observeEvent"),
  sidebarPanel(
    actionButton("evReactiveButton", "eventReactive"),
    br(),
    actionButton("obsEventButton", "observeEvent"),
    br(),
    actionButton("evReactiveButton2", "eventReactive2")
  ),
  mainPanel(
    verbatimTextOutput("eText"),
    verbatimTextOutput("oText")
  )
))

server <- shinyServer(function(input, output) {
  etext <- eventReactive(input$evReactiveButton, {
    runif(1)
  })
  observeEvent(input$obsEventButton,{
    output$oText <- renderText({ runif(1) })
  })
  eventReactive(input$evReactiveButton2,{
    print("Will not print")
    output$oText <- renderText({ runif(1) })
  })
  output$eText <- renderText({
    etext()
  })
})

shinyApp(ui=ui,server=server) 

eventReactive创建一个基于eventExpr更改的被动值,而observeEvent只是根据eventExpr

触发

答案 2 :(得分:13)

我认为这里需要强调最高级别的实践方面。

  • eventReactive创建一个定义的对象 reactive确实如此,但是你会得到通常的连锁反应行为 来自reactive。然而,它被懒惰地评估和缓存,如 其他reactives

  • observeEvent无法创建您定义的对象(它 创造别的东西)。它会立即进行评估,而不是缓存。 这是为了引起副作用。

因此,如果您需要数据框,矢量或图或其他内容,但想要与通常的反应链反应分离,请使用eventReactive

如果您只想立即产生副作用,observeEvent就是您的票。

答案 3 :(得分:4)

提供我理解的方式,纠正我并根据需要添加更多信息。大部分信息来自https://shiny.rstudio.com/articles/action-buttons.html

  • 也可能很久以前就问过这个问题,我在通过eventReactive()和observeEvent()时遇到了同样的问题
  • ObeserveEvent,更像是事件的触发器,而eventReactive更像是延迟
  • 下面我尝试使用相同的代码,同时使用反应函数
  

要构建控制同一对象的多个操作按钮,将observeEvent()调用与reactiveValues()结合使用,这里我可以使用两个同时在同一代码中工作的actionButtons。

     

Code.1给出observeElement()

的效果      

Code.2使用eventReactive(),但如果我尝试使用两个不同的actionButtons,只有最新的一个工作,前一个按钮为null并且没有反应

  • 代码1

        library(shiny)
    
        ui<-fluidPage(
          actionButton("runif", "uniform"),
          actionButton("rnorm", "Normal"),
          hr(),
          plotOutput("plot")
        )
    
        server<-function(input, output){
          v<-reactiveValues(data=NULL)
    
          observeEvent(
            input$runif,
            {
            v$data<-runif(100)
            }
          )
    
          observeEvent(
            input$rnorm,
            {
            v$data<-rnorm(100)
            }
          )
    
          output$plot <- renderPlot(
            {
              if (is.null(v$data)) return()
              hist(v$data)
            }
          )
        }
    
    shinyApp(ui, server)
    
  • 码2

       library(shiny)
    
       ui<-fluidPage(
        actionButton(inputId = "norm", label = "Normal"),
        actionButton(inputId = "unif", label = "Uniform"),
    
      #Normal
      plotOutput("hist")
    )
    
    server <- function(input, output) {
    
      dnorm <- eventReactive(input$norm, {rnorm(100)})
      dunif <- eventReactive(input$unif, {runif(100)})
    
      output$hist <- renderPlot({  
        hist(dfnorm())
      })
    
      output$hist <- renderPlot({  
        hist(dunif())
      })
    }
    
    shinyApp(ui, server)
    

答案 4 :(得分:0)

我发现this有助于理解eventReactive

eventReactives与反应堆类似,它们被构造为 如下:

eventReactive( event { 
code to run 
}) 

eventReactives不依赖于它们体内的所有反应式表达式(“ 在上面的代码段中运行)。相反,它们仅取决于 事件部分中指定的表达式。