Markdown and Latex combined with the R statistical scripting language are a popular solution to generate documents with figures. It can be a huge productivty booster to be able to both model and report at the same time.
Nonetheless it's likely one day that you will come across a situation where you will need to programatically generate cells of code. There is a recent feature in the knitr package that provides basic component templating that I will walk readers through in this tutorial.
You might need to install the missing R and Latex packages that are used within this tutorial.
Introduction
We want to generate a document in Latex that will contain static content, with the figures generated from code sections in R.
We then want dynamic sections where the cells of code are templated from a component file.
If you are used to making R Markdown documents instead, you can replace
the latex code with markdown and give it the .Rmd
file extension.
This should allow you to template components in a similar fashion.
Root document template
Let's first create a root_document_template.rnw
document that will be the base template for the Latex
document part that is static. It can includes cells of codes that generate figures.
\documentclass[landscape, a4paper]{article}
\usepackage[sfdefault]{roboto}
\usepackage[T1]{fontenc}
\usepackage[english]{babel}
\usepackage{sectsty}
\usepackage{url}
\usepackage{listings}
\usepackage{graphicx}
\usepackage{subfigure}
\usepackage{color}
\usepackage{placeins}
\usepackage{eso-pic}
\usepackage{afterpage}
\usepackage{anyfontsize}
\usepackage{setspace}
\usepackage{titlesec}
\usepackage{multicol}
\usepackage{enumitem}
\usepackage{wasysym}
\usepackage[table]{xcolor}
\usepackage{graphicx}
\usepackage{subcaption}
% recommended by kableExtra
\usepackage{float}
\usepackage{longtable}
\usepackage{array}
\usepackage{multirow}
\usepackage{booktabs}
\usepackage{wrapfig}
\usepackage{float}
\usepackage{colortbl}
\usepackage{pdflscape}
\usepackage{tabu}
\usepackage{threeparttable}
\usepackage{threeparttablex}
\usepackage[normalem]{ulem}
\usepackage{makecell}
%\usepackage{xcolor}
\usepackage{geometry}
\geometry{margin=0.6cm}
\setlength{\marginparwidth}{0px}
\setlength{\hoffset}{0px}
\setlength{\footskip}{0px}
\begin{document}
\selectlanguage{english}
\begin{multicols}{2}
{\noindent\fontsize{20}{40}\selectfont{My Report}}
\newline
\hspace{0.5cm}
{\noindent\fontsize{14}{20}\selectfont{Subtitle of my report}}
\columnbreak
\large
\begin{flushright}
{
\fontsize{14}{20}
{Written by \textbf{My Name}}
{\today}
}
\end{flushright}
\end{multicols}
\tableofcontents
% We can include libraries that would be used in components here%
<<echo=FALSE, cache=TRUE, warning=FALSE>>=
library(kableExtra)
@
\section{Introduction}
This document is a demonstration document for features of the R knit package.
It shows how to programatically generate documents, where the code defines
the content.
\section{Static Content}
This section contains a figure with a label.
\begin{center}
\begin{figure}[h]
\caption{This is a static figure with a numbered label at the top.}
<<echo=FALSE, cache=FALSE, warning=FALSE, fig.height=9, fig.width=10>>=
plot(1:10, 1:10, main="Static figure from root document")
@
\end{figure}
\end{center}
\section{Dynamic Content}
{{template_content}}
\end{document}
Note that this is not a regular Latex document, as it contains chunks of R code enclosed within delimiters. This latex document will then have a R session tied to it.
There are a few parameters for these R chunks that we are using:
- The
echo
parameter decides whether or not the code from this cell will be shown before the output. - The
cache
parameter, when true, tells that this cells result should be cached and reuse unless the code changes. When false, it always execute the code to regenerate the content. - The
warning
parameter decides whether or not R warnings are shown. - The
fig.height
andfig.width
parameters define the dimensions of the optional figures that this cell of code generates. Note that a larger width will lead your figure to be "zoomed out".
Latex Components
We now create a section_component.rnw
file that defines our component for which we will
dynamically generated instances we will later insert in the root document.
\newpage
\subsection{Section about {{component_subject}}}
\begin{center}
\begin{figure}[h]
\caption{Figure description {{component_subject}} }
<<echo=FALSE, cache=FALSE, warning=FALSE, message=FALSE, fig.height=9, fig.width=20>>=
plot({{component_multiplier}}*(1:10), 1:10, main="Dynamic figure about {{component_subject}}")
@
\end{figure}
\end{center}
\FloatBarrier
Generating the document
We will stack up code generated from this component one chunk after the other, and
we will insert all that inside the root rnw
document. Using the output rnw
file,
we will execute the R cells to obtain a tex
document. Finally, we create a PDF
using pdflatex
.
The first steps are performed from the R
scripting language:
library(knitr)
# defining the components data
components_data_df <- data.frame(
"subject"=c("Subject 1", "Subject 2", "Subject 3", "Subject 4", "Subject 5"),
"multiplier"=c(1, 2, 3, 4, 5)
)
# generating the raw content with multiple instances of the component
template_content <- NULL
for (i in seq_along(components_data_df)) {
component_multiplier <- components_data_df$multiplier[i]
component_subject <-components_data_df$subject[i]
template_content <- paste(template_content, knit_expand("section_component.rnw"), sep = "\n\n")
}
# inserting the dynamic content within the root document
template_result <- knit_expand("root_document_template.rnw")
# writing the rnw document to a file
write(template_result, "output_document.rnw")
# generating the latex and executing the R cells
knit("output_document.rnw")
Finally, an output_document.tex
file should now live inside the current
working directory, and we can make it a pdf with the following bash command:
pdflatex output_document.tex