Aktualisiere das Plot innerhalb der Beobachterschleife in einer glänzenden Anwendung

8

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%     
user3220352 22.01.2014, 11:54
quelle

2 Antworten

7

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.

    
Jeff Allen 24.01.2014 23:31
quelle
0

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.

    
Jeff Allen 22.01.2014 19:17
quelle

Tags und Links