RMarkdown Report Best Practices


I’ve built a RMarkdown/LaTeX template that I use for several different reports. I do a lot of LaTeX customization to define page styles, document header/footer, and similar things. This takes up ~70 lines in each RMarkdown report I produce, and with the exception of changing a few key things like title and date, it’s mostly the same across all reports. Right now I just copy and paste this same code into every new report I create, but that is somewhat error prone and means I also have to change multiple reports if I ever want to change this. Does anybody do something similar and is there a better way to handle this?


Would it make sense to built a .tex template and use the YAML header to handle all of the LaTeX customization?

I’ve done something like that for my reports, but I only learned enough LaTeX to make it work.



When I faced this issue a while back I weighted two options

  • creating a package with custom LaTeX template and skeleton reports to be used as a template (which seems to be the RStudio preferred way, at least according to documentation.
  • creating a single .tex template, to be referenced from each project.

At the end I chose the second option, as it allows me to recompile a report in case of future change in .tex template (this is not necessarily a good thing, but it suits my workflow).

You are welcome to check my solution on GitHub - https://github.com/jlacko/RPTG (the “report” is in Czech, so most likely unintelligible, but that does not matter - the text is Cicero’s first Catiline oration, i.e. a placeholder).

It is geared more towards corporate environment - my work is highly unlikely to appear in a respected journal, but I need to keep track of the many versions of a document floating around.


You can create a new output format with a function wrapping pdf_document:

my_latex_document <- function(..., includes = NULL) {
  header_file <- file.path("path", "to", "header.tex")
  before_file <- file.path("path", "to", "before-body.tex")
  after_file  <- file.path("path", "to", "after-body.tex")
  custom_includes <- rmarkdown::includes(
    in_header   = c(header_file, includes[["in_header"]]),
    before_body = c(before_file, includes[["before_body"]]),
    after_body  = c(after_file,  includes[["after_body"]])
  rmarkdown::pdf_document(includes = custom_includes, ...)

Of course, the way to make sure those files exist is to bundle everything up in a package. Then use system.file(...) to point to them.

Note: I only did a quick test of this function, so think of it as pseudo-code.