web-dev-qa-db-fra.com

Shiny: quelle est la différence entre observeEvent et eventReactive?

J'ai lu la documentation Shiny sur la programmation réactive à quelques reprises maintenant, mais je ne comprends pas bien la différence entre observeEvent et eventReactive.

La documentation dit:

Utilisez observeEvent lorsque vous souhaitez exécuter une action en réponse à un événement. (Notez que "recalculer une valeur" ne compte généralement pas comme une action - voir eventReactive pour cela.)

....

Utilisez eventReactive pour créer une valeur calculée qui ne se met à jour qu'en réponse à un événement. Cela ressemble à une expression réactive normale sauf qu’elle ignore toutes les invalidations habituelles qui proviennent de ses dépendances réactives;

Dans toute la situation que j'ai essayée, je ne voyais aucune différence entre observeEvent et eventReactive (le code fonctionne parfaitement quelle que soit la fonction que j'utilise, sans impact apparent sur les performances).

Pouvez-vous m'aider à comprendre quelle est la vraie différence entre les deux? Idéalement, j'aimerais quelques exemples montrant quand ils sont interchangeables, un exemple dans lequel observeEvent fonctionnerait mais pas eventReactive et vice versa.

51
lucacerone

Comme @daatali le dit, les deux fonctions sont utilisées à des fins différentes.

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 crée une valeur réactive qui change en fonction de eventExpr tandis que observeEvent est simplement déclenché en fonction de eventExpr

26
Oskar Forsmo

C'est comme la différence entre observe et reactive. L'un est destiné à être exécuté lorsqu'une variable réactive est "déclenchée" et est censé avoir des effets secondaires (observeEvent), et l'autre renvoie une valeur réactive et est destiné à être utilisé comme variable (eventReactive). Même dans la documentation de ces fonctions, la première est montrée sans être assignée à une variable (car elle est uniquement destinée à produire un effet secondaire), et la dernière est montrée comme étant assignée à une variable et utilisée plus tard.

33
DeanAttali

Je pense que les aspects pratiques du plus haut niveau doivent être soulignés ici.

  • Un eventReactive crée un objet que vous définissez comme reactive, mais sans le comportement habituel de réaction en chaîne que vous obtenez de reactive. Cependant, il est évalué et mis en cache comme l'autre reactives.

  • Un observeEvent ne peut pas créer un objet que vous définissez (cela crée autre chose). Il est immédiatement évalué et non mis en cache. C'est pour causer des effets secondaires.

Donc, si vous avez besoin d'un bloc de données, d'un vecteur, d'un tracé ou de quelque chose, mais que vous souhaitez dissocier les réactions en chaîne réactives habituelles, utilisez eventReactive.

Si vous voulez seulement provoquer un effet secondaire immédiat, observeEvent est votre ticket.

13
Mike Wise

Si je comprends bien, corrigez-moi et ajoutez plus d'informations, si nécessaire. La plupart des informations proviennent de https://shiny.rstudio.com/articles/action-buttons.html

  • Peut-être aussi cela a-t-il été demandé il y a longtemps, j'avais la même question en passant par eventReactive () et observeEventEvent ()
  • ObeserveEvent, ressemblant davantage à un déclencheur d'événement tout en eventReactive, ressemblant davantage à un délai
  • Ci-dessous, j'essaie le même code en utilisant les deux fonctions réactives.

Pour créer plusieurs boutons d'action qui contrôlent le même objet, combinez les appels observeEvent () avec reactiveValues ​​(). Ici, je peux utiliser deux actionButtons qui fonctionnent simultanément dans le même code.

Code.1 Donne l'effet de observeElement ()

Code.2 Utilise eventReactive (), mais si j'essaie d'utiliser deux actionButtons différents, seul le dernier en date fonctionne, le bouton précédent est nul et ne réagit pas.

  • 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)
    
4
Sandeep Anand