Knitr: перенаправить вывод фрагмента кода на терминал

Я хочу отслеживать довольно длинные параллельные вычисления, встроенные в файл Knitr.

Вычисления основаны на пакете, который я написал, и соответствующая функция использует mclapply из пакета multicore для распараллеливания. Эта функция выводит индикаторы выполнения для отслеживания хода вычислений с использованием слегка измененной реализации txtProgressBar из пакета utils. Индикатор выполнения выводится на терминал и обновляется через FIFO-соединение каждый раз, когда завершается итерация mclapply.

Это отлично работает при поиске из файла или непосредственном вызове функции, но я не нахожу способа заставить это работать в Knitr. Я пробовал соответствующие параметры фрагмента, я могу получать сообщения и предупреждения, перенаправляемые на терминал, но не на индикатор выполнения. Кто-нибудь может помочь?

Извините, что не предоставил минимальный рабочий пример, но я не понимаю, как я мог бы сделать его в этих настройках.


person Pepin_the_sleepy    schedule 15.11.2013    source источник


Ответы (2)


Поскольку txtProgressBar() записывает в стандартный вывод, а knitr записывает все в стандартный вывод, поэтому в настоящее время нелегко показать индикатор выполнения, если он текстовый и записывает в стандартный вывод. Возможно, я могу использовать evaluate::evaluate(debug = TRUE) для достижения того, чего вы хотите, но я не совсем уверен, что это хорошо работает с текстовым индикатором выполнения.

Мои предложения на данный момент таковы:

  • используйте индикатор выполнения на основе графического интерфейса, например tcltk::tkProgressBar()
  • записать прогресс в другие места, например. (аб)используя 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)
    ```
    
  • или используйте свою функцию вне фрагмента кода, например. во встроенном выражении (например, \Sexpr{my_multicore_function()} в Rnw или `r my_cool_fun()` в Rmd), поскольку встроенное вычисление не фиксирует стандартный вывод

person Yihui Xie    schedule 16.11.2013
comment
Спасибо за ответ @Yihui, я надеялся, что ты заглянешь! Я попробую что-то вроде вашего первого предложения, второе будет означать потерю способности кэшировать вычисления. Помимо проблем с многоядерностью, знаете ли вы какой-либо способ отслеживать состояние вычислений, выполняемых в чанке? - person Pepin_the_sleepy; 17.11.2013
comment
Возможно, вы можете записать прогресс в другие места, например, в файл: txtProgressBar(..., file = 'progress_temp.txt'). Или напишите это в stderr. Я обновлю свой ответ. - person Yihui Xie; 18.11.2013
comment
спасибо за хак StdErr(), простой в реализации и творит чудеса. Пока я этим занимаюсь, спасибо за Knitr, это потрясающий инструмент, которым я пользуюсь каждый день. - person Pepin_the_sleepy; 20.11.2013
comment
@Yihui Есть ли способ заставить Knitr не захватывать стандартный вывод? Я хочу запустить Knitr docs, но когда что-то пойдет не так, я не вижу никаких сообщений об отладке, предупреждений и т. д. - person dfrankow; 20.01.2017
comment
@YihuiXie Knitr фиксирует все в стандартном выводе Как я вижу, это верно для print(1+1), но не для symply 1+1. В этом случае нет никакого вывода в HTML или PDF. Конечно, есть вывод, если запустить 1+1 в консоли Python (2.7). Это нормальное поведение вязалки или я что-то не так делаю? - person Fran; 06.01.2019

Прочитав пункт о печати индикатора выполнения в stderr в ответе Yihui, я бы предложил временно перенаправить stdout на stderr с помощью sink().

sink(stderr())

your_code()

sink()
person konstunn    schedule 28.01.2017
comment
Это полезно, когда вы не можете контролировать, куда отправляется индикатор выполнения (например, при использовании чужого пакета, такого как rstan). - person Empiromancer; 04.04.2018