web-dev-qa-db-fra.com

Utilisation d'une expression réactive dans une instruction if en brillant

J'écris une application brillante où la sortie devrait dépendre de la valeur d'une variable qui est calculée dans une expression réactive en brillant. Au lieu de reproduire l'application réelle, je pense avoir recréé mon problème avec l'application simple suivante:

ui.R file:

   library(shiny)

   shinyUI(pageWithSidebar(

   headerPanel("Illustrating problem"),

   sidebarPanel(

   numericInput('id1', 'Numeric input, labeled id1', 0, min = 0, max = 100, step        =5)

  ),

  mainPanel(

    h4('You entered'),

    verbatimTextOutput("oid1"),

    verbatimTextOutput("odic")

  )
))

server.R file


library(shiny)

shinyServer(

  function(input, output) {

    output$oid1 <- renderPrint({input$id1})

    x<-reactive({5*input$id1})

    if (x()>50) output$oid2<-renderPrint({"You entered a number greater than 10"})

    else output$oid2<-renderPrint({"You entered a number less than or equal to 
10"})

  }
)

Si je l'exécute ainsi, j'obtiens l'erreur: Error in.getReactiveEnvironment()$currentContext(): `

Opération non autorisée sans un contexte réactif actif. (Vous avez essayé de faire quelque chose qui ne peut être fait qu'à partir d'une expression réactive ou d'un observateur.)

Si je change l'instruction if en: if (x>50) ... alors j'obtiens l'erreur:

Erreur dans x> 50: la comparaison (6) n'est possible que pour les types atomique et liste

Lorsque je change l'instruction if en: if (reactive({(x>50)})) ... alors j'obtiens le message d'erreur:

Erreur dans if (réactif ({: l'argument n'est pas interprétable comme logique

J'apprécierais grandement toute aide

8
MSR

Quelques problèmes. Le premier et le plus gros problème est que vous ne semblez pas comprendre comment fonctionne la réactivité. L'erreur indique "opération non autorisée sans un contexte réactif actif" et c'est le problème - vous accédez à x() à l'intérieur du corps principal de la fonction serveur mais pas dans un contexte réactif. Toute fonction render* Est un contexte réactif par exemple. Donc, pour résoudre ce problème, vous devez simplement déplacer l'instruction if à l'intérieur de renderPrint.

L'autre petit problème est que vos identifiants de sortie ne correspondent pas (verbatimTextOutput("odic") vs output$oid2).

Si vous ne comprenez pas la réactivité, je vous suggère fortement de prendre une demi-heure pour mieux la comprendre. Ce tutoriel a une section sur la réactivité qui peut être utile, ou vous pouvez relire le tutoriel officiel brillant de RStudio.

Voici le code de votre application fixe (j'ai supprimé un tas d'éléments d'interface utilisateur inutiles)

library(shiny)
ui <- fluidPage(
  numericInput('id1', 'Numeric input, labeled id1', 0, min = 0, max = 100, step=5),
  verbatimTextOutput("oid1"),
  verbatimTextOutput("oid2")

)
server <- function(input, output, session) {
  output$oid1 <- renderPrint({input$id1})

  x<-reactive({5*input$id1})

  output$oid2<-renderPrint({
    if (x()>50) {
      "You entered a number greater than 10"
    } else {
      "You entered a number less than or equal to 10"
    }
  })
}
shinyApp(ui = ui, server = server)
12
DeanAttali

Notez que Shiny fonctionne sur la base d'un modèle piloté par les événements - comme le font à peu près toutes les interfaces utilisateur graphiques (et aujourd'hui c'est la grande majorité). Ce n'est pas un nouveau concept, existe depuis les années 80 au moins, mais c'est plus compliqué qu'une programmation qui suit un seul organigramme - il faut un certain temps pour s'y habituer.

Quoi qu'il en soit, dans les instructions Shiny reactive et output et observe doivent être au niveau supérieur, je ne pense pas qu'il y ait d'exceptions à cela.

Vous voulez probablement quelque chose comme ça:

library(shiny)

u <- shinyUI(pageWithSidebar(

  headerPanel("Illustrating problem"),

  sidebarPanel(
    numericInput('id1', 'Numeric input, labeled id1', 0, min = 0, max = 100, step =5)
  ),

  mainPanel(

    h4('You entered'),
    verbatimTextOutput("oid1"),
    verbatimTextOutput("oid2")

  )
))

s <- shinyServer(function(input, output) {

    output$oid1 <- renderPrint({input$id1})

    x<-reactive({5*input$id1})

    output$oid2<-renderPrint({
      if (x()>50){
         "You entered a number greater than 10"
      } else {
         "You entered a number less than or equal to 10"
      }
    }
  )
}
)
shinyApp(ui = u, server = s)

Rendement:

enter image description here

5
Mike Wise