Rendering a PDF from an RMarkdown document in a Shiny app only works once

I have a Markdown document that I would like to run from a Shiny app. Here is an example Markdown document that reproduces the problem:

title: "Test Markdown report"
subtitle: "Report date: `r as.integer(format(Sys.time(), '%m'))`/`r as.integer(format(Sys.time(), '%d'))`/`r format(Sys.time(), '%Y')`"
  pdf_document: default
  MRN_patient: "01234"
  First_name_donor: "ABCD123"
urlcolor: blue
fontsize: 9pt
  \fancyhead[L]{Deceased donor assessment report}
  \fancyhead[R]{`r as.integer(format(Sys.time(), '%m'))`/`r as.integer(format(Sys.time(), '%d'))`/`r format(Sys.time(), '%Y')`}


```{r include=FALSE}

(table <- tribble(
  ~recipient, ~donor,
  "John",   "123456789"

Patient: r table$recipient, r table$donor       MRN: 123456789       ABO: A
Donor: r table$ABCD999       DOB: 1/1/1900      

#Table of typing
kbl(table, booktabs = TRUE, , caption = "Typing") %>% kable_styling(full_width = T) %>% column_spec(1, width = "2cm") %>% kable_styling(latex_options = "hold_position")

I have used these instructions: Shiny - Generating downloadable reports ( to construct a Shiny app to render this parameterized report:


ui = fluidPage(
    textInput("MRN", "Patient MRN"),
    textInput("DonorID", "Donor ID"),
    downloadButton("report", "Generate report")

server = function(input, output) {
    output$report <- downloadHandler(
      filename = "report.pdf",
      content = function(file) {
        # Copy the report file to a temporary directory before processing it, in
        # case we don't have write permissions to the current working dir (which
        # can happen when deployed).
        tempReport <- file.path(tempdir(), "temp.rmd")
        file.copy("test_RMarkdown.rmd", tempReport, overwrite = TRUE)
        # Set up parameters to pass to Rmd document
        params <- list(
          MRN_patient = input$MRN,
          First_name_donor = input$DonorID
        # Knit the document, passing in the `params` list, and eval it in a
        # child of the global environment (this isolates the code in the document
        # from the code in this app).
        rmarkdown::render(tempReport, output_file = file,
                          params = params,
                          envir = new.env(parent = globalenv())

# Run the application 
shinyApp(ui = ui, server = server)

This works beautifully, the first time. If I try to generate another report from the Shiny app, it doesn't work, and I get this error message:

! LaTeX Error: Environment tabu undefined.

Warning: Error in : LaTeX failed to compile C:\Users\BrowNich\AppData\Local\Temp\Rtmpg9bnRg\file489843723ddc.tex. See for debugging tips. See file489843723ddc.log for more info.
  [No stack trace available]

This would appear to be similar to the issue described here: r - Why does rendering a pdf from rmarkdown require closing rstudio between renders? - Stack Overflow

However, my code already contains the envir = new.env(parent = globalenv()) argument in render, and if I change to envir = new.env() I still get the same error. Closing RStudio and opening again gets it to work, but only for the first time again.

Not sure what I'm doing wrong?

I figured it out. The problem was with the kableextra package not loading properly the second time, and I used the following instructions to fix it: r - Why does rendering a pdf from rmarkdown require closing rstudio between renders? - Stack Overflow

Specifically, I added the following to the YAML header:


The linked website suggested adding \usepackage[table]{xcolor}, but that caused conflicts, so I went without it. Now I can generate pdf reports all day!

1 Like

If your question's been answered (even by you!), would you mind choosing a solution? It helps other people see which questions still need help, or find solutions if they have similar problems. Here’s how to do it:

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.