2013-11-15 22 views
8

leite ich in einer knitr Datei ein paar ziemlich lange parallelisierten Berechnungen eingebettet überwachen möchten.Knitr: chunk Code-Ausgabe an Klemme

Die Berechnungen basieren auf einem Paket, das ich geschrieben habe, und die relevante Funktion verwendet mclapply aus dem Multicore Paket für die Parallelisierung. Diese Funktion gibt Fortschrittsbalken den Fortschritt der Berechnungen zu überwachen, um eine leicht modifizierte Ausführung der txtProgressBar vom utils Paket. Der Fortschrittsbalken wird an das Terminal gedruckt und durch eine FIFO-Verbindung jedes Mal aktualisiert, wenn eine Iteration von mclapply abgeschlossen ist.

Dies funktioniert gut, wenn aus einer Datei Sourcing oder direkt die Funktion aufrufen, aber ich finde keine Möglichkeit, diese innerhalb knitr zur Arbeit zu kommen. Ich habe die relevanten Chunk-Optionen ausprobiert, ich kann Nachrichten und Warnungen an das Terminal umleiten, aber nicht den Fortschrittsbalken. Kann jemand helfen?

Sorry für das nicht ein minimales Arbeitsbeispiel bietet, aber ich sehe nicht, wie ich eine in dieser Einstellung machen könnte.

Antwort

6

Weil txtProgressBar() schreibt nach stdout, und knitr erfasst alles in stdout, so ist es derzeit nicht einfach, Ihre Fortschrittsleiste anzuzeigen, wenn es textbasiert ist und auf stdout schreibt. Vielleicht kann ich evaluate::evaluate(debug = TRUE) intern verwenden, um zu erreichen, was Sie wollen, aber ich bin mir nicht ganz sicher, ob das gut mit der Textfortschrittsleiste funktioniert.

Meine Vorschläge zur Zeit sind:

  • Verwendung eine GUI-basierte Fortschrittsbalken wie tcltk::tkProgressBar()
  • den Fortschritt an andere Orte zu schreiben, zum Beispiel (Ab) stderr

    ```{r progress} 
    pb = txtProgressBar(min = 0, max = 100, file = stderr()) 
    for (i in 1:100) { 
        setTxtProgressBar(pb, i) 
        Sys.sleep(0.05) 
    } 
    close(pb) 
    ``` 
    
  • oder verwenden Sie Ihre Funktion außerhalb eines Code Chunk, z.B. in einem Inline-Ausdruck (wie \Sexpr{my_multicore_function()} in Rnw oder `r my_cool_fun()` in Rmd), weil Inline-Auswertung nicht erfasst stdout

+0

Danke für die Antwort @Yihui, ich hatte gehofft, Sie würden vorbeikommen! Ich werde etwas auf der Linie Ihres ersten Vorschlags versuchen, das zweite würde bedeuten, die Fähigkeit zu verlieren, die Berechnungen zu cachen. Haben Sie Kenntnis von Multicore-Problemen, um den Status von Berechnungen zu überwachen, die in einem Chunk ausgeführt werden? –

+1

Vielleicht können Sie den Fortschritt an andere Stellen schreiben, zum Beispiel in eine Datei: 'txtProgressBar (..., file = 'progress_temp.txt')'. Oder schreibe es an stderr. Ich werde meine Antwort aktualisieren. –

+0

danke für den 'StdErr()' Hack, einfach zu implementieren und wirkt Wunder. Während ich dabei bin, danke für Knitr, es ist ein tolles Werkzeug, das ich täglich benutze. –

0

über das Drucken Fortschrittsbalken den Punkt gelesen Nachdem in Yihui Antwort auf stderr würde ich vorübergehend vorschlagen Umleitung stdout zu stderr mit sink().

sink(stderr()) 

your_code() 

sink()