2016-07-29 17 views
0

Ich bin auf eine Situation gestoßen, in der ein reaktiver Ausdruck mehrfach ausgewertet wird, wenn er einige Eingaben in renderUI-Widgets aufruft.R Glänzende, sich wiederholende Auswertung des reaktiven Ausdrucks

Bitte überprüfen Sie den folgenden einfachen Code.

library(shiny) 


server <- function(input, output) { 
    output$INPUT_1 = renderUI({ 
    selectInput("input_1","Input 1",choices = letters) 
    }) 
    output$INPUT_2 = renderUI({ 
    selectInput("input_2","Input 2",choices = letters) 
    }) 
    output$INPUT_3 = renderUI({ 
    selectInput("input_3","Input 3",choices = letters)  
    }) 
    output$INPUT_4 = renderUI({ 
    selectInput("input_4","Input 4",choices = letters)  
    }) 


    output$text = renderText({ 
    print("1") 
    paste(input$input_1,input$input_2,input$input_3,input$input_4) 
    }) 

} 

ui <- fluidPage(
    uiOutput("INPUT_1"), 
    uiOutput("INPUT_2"), 
    uiOutput("INPUT_3"), 
    uiOutput("INPUT_4"), 
    textOutput("text") 
) 

shinyApp(ui = ui, server = server) 

Wenn Sie einen Blick auf Ihre Konsole nehmen, werden Sie

Listening on http://127.0.0.1:4939 
[1] "1" 
[1] "1" 

Die "1" kam zweimal sehen.

Meine eigene App hat die "1" kommt mehr als 3 mal. Da jedes meiner reaktiven Geschäfte mit Big Data handelt, ist diese Art von Szenario wirklich peinlich für meine Benutzer und mich.

Ich bin mir fast sicher, dass dies etwas mit der RenderUI-Einrichtung zu tun hat. Aber ich kann immer noch keinen Weg finden, es zu reparieren. Ich überlegte, updateXXXXX-Funktionen zu verwenden, aber meine Eingabe-UIs enthalten sehr komplexe Berechnungen. Die Verwendung von updateXXXXX ist etwas, das ich vermeiden möchte.

Wie kann der my reaktive Ausdruck nur einmal ausgewertet werden?

+0

Ein reaktiver Ausdruck wird jedes Mal ausgewertet, wenn sich ein (verknüpftes) ui-Element ändert. Der Server wird also ausgewertet, wenn die App geladen wird und alle Eingaben leer sind. Dann werden die reaktiven UI-Elemente gefüllt und Ihr Druck wird ein zweites Mal ausgewertet. (add if (length (input $ input_1)> 0) drucke ("1") als Beispiel auf die Ausgabe $ text) – Arcoutte

Antwort

1

Shiny kommt mit einer zusätzlichen Funktion namens req, die Ihnen hilft, die Ausführung von Beobachtern zu steuern, obwohl einige Steuerelemente während eines serverseitigen Aufrufs im Fluge gerendert werden. Die vollständige Dokumentation finden Sie unter this page here. Kurz gesagt, Sie können eine Reihe von Eingangsvariablen innerhalb einer reaktiven Umgebung auflisten (Observer, reaktiver Wert oder Renderfunktion), und diese reaktive Umgebung wird erst berechnet/ausgeführt, wenn allen Eingangsvariablen ein Wert zugewiesen wurde.

In Ihrem Fall können Sie die Zeile

req(input$input_1, input$input_2,input$input_3, input$input_4) 

zu Ihrem Beobachter fügen Sie einfach und es wird nur einmal durchgeführt werden. (Es wurde zweimal aus den in Arcoutte's Kommentar zu Ihrem Beitrag angegebenen Gründen ausgeführt.)

Vollständiger Beispielcode unten.

library(shiny) 

server <- function(input, output) { 
    output$INPUT_1 = renderUI({ 
    selectInput("input_1","Input 1",choices = letters) 
    }) 
    output$INPUT_2 = renderUI({ 
    selectInput("input_2","Input 2",choices = letters) 
    }) 
    output$INPUT_3 = renderUI({ 
    selectInput("input_3","Input 3",choices = letters)  
    }) 
    output$INPUT_4 = renderUI({ 
    selectInput("input_4","Input 4",choices = letters)  
    }) 


    output$text = renderText({ 
    req(input$input_1,input$input_2,input$input_3,input$input_4) 

    print("1") 
    paste(input$input_1,input$input_2,input$input_3,input$input_4) 
    }) 

} 

ui <- fluidPage(
    uiOutput("INPUT_1"), 
    uiOutput("INPUT_2"), 
    uiOutput("INPUT_3"), 
    uiOutput("INPUT_4"), 
    textOutput("text") 
) 

shinyApp(ui = ui, server = server) 
+0

Danke. Das hat mein Problem perfekt gelöst. – John

Verwandte Themen