Glänzend: Was ist der Unterschied zwischen ObservEvent und EventReactive?

73

Ich habe die Shiny-Dokumentation über reaktive Programmierung jetzt einige Male gelesen, aber ich kann den Unterschied zwischen observeEventund nicht richtig verstehen eventReactive.

Die Dokumentation sagt:

Verwenden Sie watchEvent, wenn Sie eine Aktion als Reaktion auf ein Ereignis ausführen möchten. (Beachten Sie, dass "Neuberechnung eines Werts" im Allgemeinen nicht als Ausführung einer Aktion gilt - siehe dazu eventReactive.)

....

Verwenden Sie eventReactive, um einen berechneten Wert zu erstellen, der nur als Reaktion auf ein Ereignis aktualisiert wird. Dies ist wie ein normaler reaktiver Ausdruck, außer dass alle üblichen Ungültigmachungen ignoriert werden, die sich aus seinen reaktiven Abhängigkeiten ergeben.

In all den Situationen, in denen ich es versucht habe, habe ich keinen Unterschied zwischen observeEventund gesehen eventReactive(der Code funktioniert einwandfrei, unabhängig von der von mir verwendeten Funktion, ohne erkennbare Auswirkungen auf die Leistung).

Können Sie mir helfen, herauszufinden, was der wahre Unterschied zwischen den beiden ist? Idealerweise möchte ich ein paar Beispiele, die zeigen, wann sie austauschbar sind, eines, wenn observeEventes funktionieren würde, aber nicht eventReactiveund umgekehrt.

Lucaceron
quelle

Antworten:

38

Wie @daatali sagt, werden die beiden Funktionen für unterschiedliche Zwecke verwendet.

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) 

eventReactiveErstellt einen reaktiven Wert, der sich basierend auf ändert, eventExprwährend observeEventeinfach basierend auf ausgelöst wirdeventExpr

OsFo
quelle
44

Es ist wie der Unterschied zwischen observeund reactive. Eine soll ausgeführt werden, wenn eine reaktive Variable "ausgelöst" wird und Nebenwirkungen haben soll ( observeEvent), die andere gibt einen reaktiven Wert zurück und soll als Variable verwendet werden ( eventReactive). Selbst in der Dokumentation für diese Funktionen wird die erstere gezeigt, ohne einer Variablen zugewiesen zu sein (weil sie nur einen Nebeneffekt hervorrufen soll), und die letztere wird gezeigt, um einer Variablen zugewiesen und später verwendet zu werden.

DeanAttali
quelle
Ist es möglich, dass ein reactiveValuesObjekt a "empfängt" eventReactive? Soweit ich weiß, reactiveValuesähnelt a a reactive, aber ich habe nur Beispiele für den observeEventUmgang mit ihnen gelesen . Ich bin mir nicht sicher, ob dieser Kommentar wirklich im Rahmen dieses Threads liegt ... aber wenn dies der Fall ist, kann ich einen neuen öffnen ...
user5029763
2
Hervorragender Hinweis zum variablen Speicher.
d8aninja
16

Ich denke, die praktischen Aspekte der obersten Ebene müssen hier hervorgehoben werden.

  • An eventReactiveerstellt ein Objekt, das Sie wie reactivegewohnt definieren , jedoch ohne das übliche Kettenreaktionsverhalten, von dem Sie ausgehen reactive. Es wird jedoch träge ausgewertet und wie das andere zwischengespeichert reactives.

  • Ein observeEventObjekt, das Sie definieren, kann nicht erstellt werden (es wird etwas anderes erstellt). Es wird sofort ausgewertet und nicht zwischengespeichert. Es ist für die Verursachung von Nebenwirkungen.

Wenn Sie also einen Datenrahmen oder Vektor oder eine Darstellung oder etwas anderes benötigen, sich aber von den üblichen reaktiven Kettenreaktionen entkoppeln möchten, verwenden Sie eventReactive.

Wenn Sie nur eine sofortige Nebenwirkung verursachen möchten, observeEventist Ihr Ticket.

Mike Wise
quelle
4

Wenn Sie dies so verstehen, korrigieren Sie mich und fügen Sie nach Bedarf weitere Informationen hinzu. Die meisten Informationen stammen von https://shiny.rstudio.com/articles/action-buttons.html

  • Vielleicht wurde dies auch schon vor langer Zeit gestellt. Ich hatte die gleiche Frage, als ich eventReactive () durchlief und Event () beobachtete.
  • ObeserveEvent ist eher ein Auslöser für ein Ereignis, während eventReactive eher eine Verzögerung ist
  • Im Folgenden versuche ich den gleichen Code mit beiden reaktiven Funktionen

Um mehrere Aktionsschaltflächen zu erstellen, die dasselbe Objekt steuern, kombinieren Sie Aufrufe von compareEvent () mit reactiveValues ​​(). Hier kann ich zwei actionButtons verwenden, die gleichzeitig im selben Code arbeiten.

Code.1 Gibt die Wirkung von ObservElement ()

Code.2 Verwendet eventReactive (), aber wenn ich versuche, zwei verschiedene actionButtons zu verwenden, funktioniert nur die neueste. Die frühere Schaltfläche ist null und hat nicht reagiert

  • Code 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)
    
  • Code2

       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)
    
Sandeep Anand
quelle