Shiny:observeEvent 和 eventReactive 有啥区别?

Posted

技术标签:

【中文标题】Shiny:observeEvent 和 eventReactive 有啥区别?【英文标题】:Shiny: what is the difference between observeEvent and eventReactive?Shiny:observeEvent 和 eventReactive 有什么区别? 【发布时间】:2016-02-04 19:51:09 【问题描述】:

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

文档说:

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

....

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

在我尝试的所有情况下,我发现使用 observeEventeventReactive 没有区别(无论我使用什么功能,代码都可以正常工作,对性能没有明显影响)。

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

【问题讨论】:

【参考方案1】:

正如@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 触发

【讨论】:

fwiw Joe Cheng 称从观察者内部分配渲染函数的输出是一种“反解决方案”,“通常意味着作者对分配渲染代码块的含义有一个基本的误解一个输出槽”。我还没有完全理解这意味着什么。 rstudio-pubs-static.s3.amazonaws.com/…【参考方案2】:

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

【讨论】:

是否有可能让reactiveValues 对象“接收”eventReactive?据我了解,reactiveValues 类似于reactive,但我只阅读了observeEvent 处理它们的示例。不确定这个评论是否真的在这个帖子的范围内......但如果是这样的话,我可以打开一个新的...... 关于变量存储的出色说明。【参考方案3】:

我认为这里需要强调顶层的实际方面。

eventReactive 创建一个定义的对象 reactive 可以,但没有通常的连锁反应行为 来自reactive。然而,它被懒惰地评估和缓存,就像 其他reactives

observeEvent 无法创建您定义的对象(它 创造别的东西)。它立即被评估并且不被缓存。 这是为了引起副作用。

因此,如果您需要数据框、向量、绘图或其他内容,但又想从通常的反应性链式反应中解耦,请使用 eventReactive

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

【讨论】:

【参考方案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)

【讨论】:

在code2中,你有一个错字:hist(dfnorm()) 而不是hist(dnorm())【参考方案5】:

我发现this 有助于理解eventReactive

eventReactives 类似于响应式,它们被构造为 如下:

eventReactive( event  
code to run 
) 

eventReactives 不依赖于其主体中的所有反应式表达式('code to 在上面的 sn-p 中运行)。相反,它们只依赖于 事件部分中指定的表达式。

【讨论】:

以上是关于Shiny:observeEvent 和 eventReactive 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

R Shiny:在 ObserveEvent 中更新代理表列标题

在R Shiny中,如何用observe替换observeEvent?

数据框不会在 Shiny R 中使用 observeEvent 更新

闪亮,observeEvent,updateSelectInput,输入重置

在 r shiny 中使用 pickerInput 来应用函数

Shiny 应用程序在执行大计算时停止