Ich habe eine Simulation in R geschrieben, die ich jetzt mit glänzend visualisieren möchte. Ich habe den Hauptteil der Simulation in einen beobachten -Block gelegt, um ausgewertet zu werden. Während dieses Evaluierungsprozesses, d. H. Für jede Iteration, möchte ich den aktuellen Status darstellen. Die Frage ist, wie kann ich dies erreichen, da in meinem tatsächlichen Code das Rendern des Plots nur ausgeführt wird, nachdem der Hauptbeobachter evaluiert wurde. Gibt es eine Möglichkeit, zum Beispiel die Ausführung des Beobachtungsblocks zu unterbrechen und nach der Aktualisierung des Diagramms fortzusetzen?
Sollte es nicht noch mehr Funktionalität von shiny geben, um einen solchen Fall anzugehen, da ich mir vorstellen kann, dass ich nicht der einzige bin, der so etwas machen möchte ?!
Es wäre schön, wenn Sie mir dabei helfen könnten:)
Unten ist ein Skelett-Code für den Server und ui.
ui.R:
%Vor%server.R:
%Vor% Ich habe ein bisschen mehr darüber nachgedacht. Ich denke, die richtige Lösung besteht darin, invalidateLater
zu verwenden, um die Ausführung von Aufgaben in kleinen Blöcken zu planen, aber andere reaktive Abhängigkeiten zuzulassen, um unseren lang andauernden Prozess zu unterbrechen, um beispielsweise Graphen zu aktualisieren.
Ich habe ein schnelles Beispiel in Ссылка zusammengestellt. Sie können dies mit
ausführen %Vor%Die Grundvoraussetzung ist, dass wir einige lang andauernde iterative Berechnungen wie in Ihrer Simulation durchführen, aber wir tun dies in kleineren Teilen, damit andere Reaktiva dazwischen laufen können. Mein Code ist wirklich einfach auszuführen, so dass ich 100.000 Wiederholungen meiner Schleife in ~ 1 Sekunde verarbeiten kann. Dabei geht es darum, wie lange ich warten möchte, bis meine App interaktiv aktualisiert wird. Ich möchte 5 Millionen Iterationen durchführen, also plane ich 50 Chunks.
Jedes Mal, wenn ich einen Teil von 100.000 Iterationen durchführe, aktualisiere ich ein paar reaktive Werte, die einige andere Updates hervorbringen, die in einer renderText
an meine Benutzeroberfläche gesendet werden (obwohl ein renderPlot
wie deiner funktionieren würde) genau das gleiche). Wenn Sie die App ausführen, sehen Sie, dass diese Reaktiva zwischen den einzelnen Chunks aktualisiert werden, die ich vor Ausführung des nächsten Chunks ausgeführt habe.
Bei dieser Methode gibt es einen gewissen Overhead, so dass Ihre Berechnung möglicherweise etwas langsamer wird. Aber auf meinem Rechner benötigten 5 Millionen Iterationen 21 Sekunden, wenn sie alle gleichzeitig auf der Konsole ausgeführt wurden, und 23 Sekunden in diesem verzögerten Dispatch-Modell. Du könntest das natürlich weiter runter treiben, indem du größere Stücke machst.
Lass mich wissen, was du denkst. Ich denke, es könnte Sinn machen, dies zusammenzufassen und Teile davon in Shiny oder als Erweiterungspackung einzubauen.
Da Sie in Ihrem Code einen Aufruf Sys.sleep()
haben, gehe ich davon aus, dass Sie nur eine Iteration pro Sekunde durchlaufen möchten. Wenn dies der Fall ist, können Sie reactiveTimer
festlegen, die den Code jede Sekunde auswerten. Innerhalb dieses Timers würden Sie den Code für die aktuelle Iteration ausführen und dann die Variable dummy$iter
erhöhen.