Почему рендеринг pdf файла из rmarkdown требует закрытия rstudio между рендерами?

Фон

Я пытаюсь сделать документ rmarkdown, который отображается с помощью render(). Вызов render имеет два элемента, которые параметризуются:

  • Я хотел бы, чтобы пользователь мог указать pdf или html. Прямо с помощью output_format().
  • Я также хотел бы передать параметр в документ, чтобы указать, являются ли таблицы (с использованием пакета kableExtra) латекс или html.

Это файл rmarkdown, называемый test.Rmd

---
title: "Title"
author: "Zzz Zzzzzz"
params:
  table_format:
    value
---

```{r setup}
knitr::opts_chunk$set(echo = FALSE)
library(knitr)
library(kableExtra)

options(knitr.table.format = params$table_format) 
```

## Test table

```{r cars}
if (params$table_format == "latex"){
kable(iris[1:100,], booktabs = T) %>%
  kable_styling(latex_options = c("scale_down")) 
}

if (params$table_format == "html"){
kable(iris[1:100,]) %>%
  kable_styling(bootstrap_options = c("striped", "hover"))  %>%
  scroll_box(width = "500px", height = "600px")
}


params$table_format
```

Теперь вот два вызова для визуализации файла:

rmarkdown::render("test.Rmd", output_format = "pdf_document", params = list(
  table_format = "latex"
))


rmarkdown::render("test.Rmd", output_format = "html_document", params = list(
  table_format = "html"
))

Проблема

Теперь, если я открою новый сеанс rstudio, я могу запускать обе render вызовы без проблем. Создается файл .pdf или .html. Однако, если я попытаюсь снова запустить рендеринг .pdf, я получаю следующую ошибку:

"C:/Program Files/RStudio/bin/pandoc/pandoc" + RTS -K512m -RTS test.utf8.md - в латекс - от уценки + autolink_bare_uris + ascii_identifiers + tex_math_single_backslash --output test.pdf --template "C:\Users\salbers\R\win-library\3.4\rmarkdown\rmd\latex\default-1.17.0.2.tex" -highlight-style tango --latex-engine pdflatex - переменная графика = да - переменная "geometry: margin = 1in"! Undefined контроль последовательность. \begin {tabular} {rrrrl}\toprule                                             Sepal.Length и Sepal.Width и Pet... l.267\end {tabular}}

pandoc.exe: ошибка при создании PDF-ошибки: преобразование документа pandoc Ошибка с ошибкой 43 Кроме того: Предупреждающее сообщение: команда запуска '' C:/Program Files/RStudio/bin/pandoc/pandoc "+ RTS -K512m -RTS test.utf8.md - в латекс - от уценки + autolink_bare_uris + ascii_identifiers + tex_math_single_backslash --output test.pdf --template "C:\Users\salbers\R\win-library\3.4\rmarkdown\rmd\latex\default-1.17.0.2.tex" -highlight-style tango --latex-engine pdflatex - переменная графика = да - переменная "geometry: margin = 1in" 'имеет статус 43

Html-рендеринг работает отлично снова и снова. Если я закрою rstudio, тогда запустите проект, рендеринг для PDF тоже будет работать отлично.

Вопрос

  • Может ли кто-нибудь сказать мне, почему мой документ pdf rindingdown не может быть представлен дважды в одном сеансе rstudio?
  • Аналогично, почему rstudio приходится закрывать между визуализацией?

Ответ 1

ОБНОВЛЕНИЕ 2019-01-21:

Одно из больших различий между кнопкой вязания и функцией render заключается в том, что кнопка вязания всегда начинается с "новой среды" (как мы все можем чувствовать), тогда как функция render по умолчанию запускается в parent.env().

render(input, ..., envir = parent.frame(), ...)

В документации по функциям мы видим

envir   
The environment in which the code chunks are to be evaluated 
during knitting (can use new.env() to guarantee an empty new 
environment).

Поэтому мы можем смоделировать поведение нажатия кнопки knit, поместив envir = new.nev() в вызове рендеринга.


Оригинальный ответ:

Хм, позвольте мне сначала опубликовать решение. Чтобы решить эту проблему, вам нужно поместить следующие вещи в ваш раздел yaml. Я также добавил функцию kableExtra_latex_packages() в версии для разработчиков в начале этой недели, чтобы вызвать следующие тексты.

header-includes:
  - \usepackage{booktabs}
  - \usepackage{longtable}
  - \usepackage{array}
  - \usepackage{multirow}
  - \usepackage[table]{xcolor}
  - \usepackage{wrapfig}
  - \usepackage{float}
  - \usepackage{colortbl}
  - \usepackage{pdflscape}
  - \usepackage{tabu}
  - \usepackage{threeparttable}
  - \usepackage[normalem]{ulem}

Если вам интересно, почему существует такое странное поведение, вот краткое объяснение. При первой загрузке kableExtra в rmarkdown environement, он будет пытаться поместить информацию LaTeX пакет выше в метаданные rmarkdown с помощью usepackage_latex() функцию, которая поставляется с этим пакетом. Это прекрасно работает, если вы просто нажмете кнопку вязания, потому что каждый процесс "вязание + рендеринг" должен быть изолированным. Однако, как это ни удивительно (кстати, спасибо, что поднял его), как мы видим здесь, если вы пытаетесь выполнить рендеринг с консоли, так как (мое предположение) knitr или rmarkdown пытается повторно использовать некоторые кэшированные результаты, этот процесс не удалось воспроизвести. Оказывается, что эти зависимости пакета LaTeX не были помещены в генерируемый текстовый файл и заканчиваются ошибкой. Если вы закроете RStudio и перезапустите его, конечно, его временная память исчезнет, и вы сможете снова загрузить эти пакеты. Я чувствую, что это может быть ошибка, связанная с глобальными переменными в rmarkdown. Я думаю, что мы можем это исправить, добавив часть "забыть мета" в конце функции render но мне нужно это посмотреть.

Отчасти это было плохо, потому что я не предоставил достаточно документации по пакетам LaTeX, которые использовались в прошлых выпусках. Теперь я добавил новый раздел об этой проблеме в самом начале пакета виньеток kableExtra 0.5.0, который был выпущен ранее на этой неделе. Не стесняйтесь проверить это. Также, как я уже говорил ранее, в текущей версии разработчика вы можете вызвать список, используя функцию kableExtra_latex_packages().

Ответ 2

В моем случае ответ @Hao не сработал... Наконец, мне удалось выгрузить пакет kableExtra после каждого выполнения рендеринга, как показано ниже:

rmarkdown::render('torender.Rmd')
detach("package:kableExtra", unload=TRUE)

Должно быть возможно также выбрать среду, используя что-то вроде

rmarkdown::render('torender.Rmd',envir=new.env(some parameters))

который чище.... но я так не справился!

Ответ 3

У меня была похожая проблема: цикл для рендеринга отчетов в формате PDF, содержащих таблицу. PDF не рендерится с booktabs = T. Мое решение состояло в том, чтобы вручную загрузить все латексные пакеты в моем установочном чанке в сценарии Rmd, который вызывался из цикла.

Итак, в сценарии Rmd, который вызывался несколько раз, у меня есть:

usepackage_latex("booktabs")
usepackage_latex("longtable")
usepackage_latex("array")
usepackage_latex("multirow")
usepackage_latex("xcolor", "table")
usepackage_latex("wrapfig")
usepackage_latex("float")
usepackage_latex("colortbl")
usepackage_latex("pdflscape")
usepackage_latex("tabu")
usepackage_latex("threeparttable")
usepackage_latex("threeparttablex")
usepackage_latex("ulem", "normalem")
usepackage_latex("makecell")

Это решило проблему - PDF файлы отображались в отформатированных таблицах.

Надеюсь, это кому-нибудь поможет.

Ответ 4

Я нашел простой способ сделать это для нескольких файлов .Rmd - создать файл "headers.tex" со списком этих команд kableExtra-Added\usepackage {}. Затем в заголовке YAML файла .Rmd:

output: 
  pdf_document:
    includes:
      in_header: headers.tex

Вот что я поместил в файл header.tex - я скопировал его из файла, который работал, а также вывод kableExtra_latex_packages(), убирающий строку "header-includes:" и тире.

\usepackage{booktabs}
\usepackage{longtable}
\usepackage{array}
\usepackage{multirow}
\usepackage{wrapfig}
\usepackage{float}
\usepackage{colortbl}
\usepackage{pdflscape}
\usepackage{tabu}
\usepackage{threeparttable}
\usepackage{threeparttablex}
\usepackage[normalem]{ulem}
\usepackage{makecell}
\usepackage{xcolor}