Shiny:observeEvent和eventReactive有什么区别?

luc*_*one 54 r reactive-programming shiny shiny-server

现在我几次读到反应式编程的闪亮的文档,但我不能正确理解之间的差异observeEventeventReactive.

文件说:

只要您想执行响应事件的操作,请使用observeEvent.(请注意,"重新计算值"通常不会被视为执行操作 - 请参阅eventReactive.)

....

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

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

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

Dea*_*ali 37

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

  • 关于变量存储的优秀注意事项. (2认同)

Osk*_*smo 28

正如@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) 
Run Code Online (Sandbox Code Playgroud)

eventReactive创建一个基于eventExprwhile observeEvent简单地基于while而发生变化的被动值eventExpr

  • fwiw Joe Cheng 称从观察者内部分配渲染函数的输出为“反解决方案”,这“通常意味着作者对将渲染代码块分配给输出槽的含义存在根本性的误解”。我还没有完全理解这意味着什么。https://rstudio-pubs-static.s3.amazonaws.com/192350_d3385f81117e4506a090da03ac8d3361.html#solution (2认同)

Mik*_*ise 14

我认为这里需要强调顶级实践方面.

  • 一个eventReactive创建了一个对象,你这样定义 reactive,不过它通常出连锁反应的行为,你从中获取reactive.然而,它被懒惰地评估和缓存,就像另一个reactives.

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

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

如果你只是想立即产生副作用,那observeEvent就是你的票.


San*_*and 5

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

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

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

Code.1 给出了observeElement()的效果

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

  • 代码 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)
    
    Run Code Online (Sandbox Code Playgroud)
  • 代码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)
    
    Run Code Online (Sandbox Code Playgroud)