2017-12-12 9 views
0

Ich habe seit Stunden auf dieses Problem stecken. Ich habe versucht, eine einfachere Version meines tatsächlichen Anwendungsfalls zu erstellen, um zu sehen, ob ich das Problem beheben kann, aber immer noch Probleme habe.Reaktive Schleife in R Shiny

Meine glänzende App ist unten. Es nimmt eine Eingabe vom Benutzer, führt es durch einige Berechnungen, bis es einen Schwellenwert erreicht, und sammelt dann den Wert in einer Liste. Dies geschieht für mehrere Iterationen (10 hier im Beispiel), dann wird ein Histogramm dieser Werte gezeichnet.

Der genaue Fehler Ich erhalte sagt

Warning: Error in : evaluation nested too deeply: infinite recursion/options(expressions=)? 

Ich denke, dass meine Fehler auf dem Weg zusammenhängt ich x.new bin, aber ich kann nicht herausfinden, wie es anders zu codieren.

# install.packages('shiny') 
library(shiny) 
ui <- fluidPage(
    headerPanel('Title Here'), 
    sidebarPanel(
    numericInput('x.qty', 'Pick a number', 3, 1, 10)), 
    mainPanel(plotOutput('valueplot')) 
) 

server <- function(input, output, session) { 
    results <- reactive({ 
    x.list <- list() 
    for (i in 1:10){ 
     x.new <- reactive({input$x.qty * sample(1:10, 1)}) 
     repeat{ 
     if (x.new() > 20){ 
      x.list <- c(x.list, x.new()) 
      results <- x.list 
      break 
     } # end if loop 
     x.new <- reactive({x.new() * sample(1:10, 1)}) 
     } # end repeat 
    } # end for loop 
    results 
    }) 
    output$valueplot <- renderPlot({hist(as.numeric(results()))}) 
} 

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

Das grundlegende Problem hier ist, dass 'x.new()' eine reaktive ist, die mehr als einmal definiert ist, so glänzend weiß nicht, was es sein sollte. Kannst du das umschreiben, um das zu vermeiden, vielleicht indem du eine reaktive Variable oder nur zwei verschiedene Namen benutzt? –

+0

Das Problem ist, ich brauche es als Referenz. Also, Benutzer wählt 3 für 'x.qty' ...' x.new' multipliziert 3 mit einer Zufallszahl ... sagen wir 2 zum Beispiel. Das ist nicht größer als 20, also möchte ich, dass der neue Wert von x.new 6 ist und mit einer anderen Zahl multipliziert wird. – pyll

Antwort

1

Ich würde vorschlagen, Ihre Server-Funktion in der folgenden Art und Weise zu ändern:

server <- function(input, output, session) { 
    results <- reactive({ 
    x.list <- list() 
    for (i in 1:10){ 
     x.new <- input$x.qty * sample(1:10, 1) 
     repeat{ 
     if (x.new > 20){ 
      x.list <- c(x.list, x.new) 
      results <- x.list 
      break 
     } # end if loop 
     x.new <- x.new * sample(1:10, 1) 
     } # end repeat 
    } # end for loop 
    results 
    }) 
    output$valueplot <- renderPlot({hist(as.numeric(results()))}) 
} 

Auf diese Weise können die unendliche Rekursion von

x.new <- reactive({x.new() * sample(1:10, 1)}) 
provoziert vermeiden 210
+0

Dies hat die gewünschte Ausgabe und sieht ein wenig sauberer als die andere Antwort. – pyll

1

Funktioniert das wie gewünscht? Jede for Schleifeniterationslatenzzeit wird x.new berechnet x.qty dann in der repeat Schleife x.new selbst rekursiv durch eine Zufallszahl multipliziert, bis er größer ist als 20.

library(shiny) 

ui <- fluidPage(headerPanel('Title Here'), 
       sidebarPanel(numericInput('x.qty', 'Pick a number', 3, 1, 10)), 
       mainPanel(plotOutput('valueplot'))) 

server <- function(input, output, session) { 

    x.new <- function(x) { 
    x * sample(1:10, 1) 
    } 

    results <- reactive({ 
    x.list <- list() 
    for (i in 1:10) { 
     x.new_draw <- x.new(input$x.qty) 
     repeat { 
     if (x.new_draw > 20) { 
      x.list <- c(x.list, x.new_draw) 
      break 
     } # end if loop 
     x.new_draw <- x.new(x.new_draw) 
     } # end repeat 
    } # end for loop 
    x.list 
    }) 
    output$valueplot <- renderPlot({ 
    hist(as.numeric(results())) 
    }) 

} 

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

Ja! Das scheint genau das zu sein, wonach ich suche. Könnten Sie eine kurze Erklärung hinzufügen, warum das funktioniert? – pyll

+0

Hi Entschuldigung späte Antwort. Die Funktion "x.new" multiplizierte einfach eine Zahl mit einer Zufallszahl, sodass sie nicht reaktiv sein musste. Ich habe es als eine Funktion nur aus Gewohnheit verwendet - wenn Sie die Zufallszahlengenerierung ändern möchten, müssen Sie es nur an einer Stelle im Vergleich zu der anderen Antwort ändern. Außerdem akkumulieren Sie bereits Ergebnisse in 'x.list', so dass es nicht notwendig ist, diese in 'results' zu kopieren, da dieser Vektor mit der reaktiven Funktion, die auch' result' genannt wird, verwechselt werden kann, auch wenn sie unterschiedlich sind. Sie können einfach 'x.list' am Ende zurückgeben – hrabel

Verwandte Themen