[Tex/LaTex] Building TeX file from knitr Rnw as child of larger parent TeX file to use R objects and output

knitrrsweavetemplates

Here's my general problem: I'm writing my dissertation using a LaTeX template (http://www.latextemplates.com/template/masters-doctoral-thesis). The template is a parent file with multiple chapters as children. For some of the chapters, I want to include objects and output from R, whereas for other chapters (e.g., Introduction) I don't want to use R. For the chapters without R, I've created the .TeX files as part of the template.

Here's my specific problem: Right now I'm using knitr to create .TeX files with R objects and output. I'm open to using other options (e.g., sweave) if they'll work better for what I'm trying to do. I have some .TeX files without R objects from a dissertation template that I want to combine with .Rnw (or other) files with R objects. I want the .Rnw files to be created as child .TeX files of the larger parent .TeX file. The parent-child structure works for my .TeX files as part of the template using \input{}. However, I'm having trouble getting the .TeX files created from the .Rnw files to be included as child .TeX files. I've seen resources for combining .Rnw files as child files of a larger parent .Rnw file (here), but they appear to be combining only .Rnw files, not .Rnw files (with R) with .TeX files (without R).

Because my template structure has a parent file, that's where I specify the documentclass, begin document, etc. As a result, the child .TeX files don't have headers. Thus, I first tried to create a .Rnw file without the documentclass and begin document headers, but when I knit the .Rnw file into .TeX and build the LaTeX files from all of the .TeX files, I receive the following error:

! LaTeX Error: Environment knitrout undefined.

However, if I include the header in the .Rnw file with documentclass and begin document, I receive the following error:

! LaTeX Error: Can be used only in preamble.

Below is the .Rnw file I'm using (with the header):

\documentclass{article}

\begin{document}

Here is a code chunk.

>=
1+1
letters
chartr('xie', 'XIE', c('xie yihui', 'Yihui Xie'))
par(mar=c(4, 4, .2, .2)); plot(rnorm(100))
@

You can also write inline expressions, e.g. $\pi=\Sexpr{pi}$, and \Sexpr{1.598673e8} is a big number.

\end{document}

Below is the .TeX file generated from the .Rnw file:

\documentclass{article}\usepackage[]{graphicx}\usepackage[]{color}
%% maxwidth is the original width if it is less than linewidth
%% otherwise use linewidth (to make sure the graphics do not exceed the margin)
\makeatletter
\def\maxwidth{ %
  \ifdim\Gin@nat@width>\linewidth
    \linewidth
  \else
    \Gin@nat@width
  \fi
}
\makeatother

\definecolor{fgcolor}{rgb}{0.345, 0.345, 0.345}
\newcommand{\hlnum}[1]{\textcolor[rgb]{0.686,0.059,0.569}{#1}}%
\newcommand{\hlstr}[1]{\textcolor[rgb]{0.192,0.494,0.8}{#1}}%
\newcommand{\hlcom}[1]{\textcolor[rgb]{0.678,0.584,0.686}{\textit{#1}}}%
\newcommand{\hlopt}[1]{\textcolor[rgb]{0,0,0}{#1}}%
\newcommand{\hlstd}[1]{\textcolor[rgb]{0.345,0.345,0.345}{#1}}%
\newcommand{\hlkwa}[1]{\textcolor[rgb]{0.161,0.373,0.58}{\textbf{#1}}}%
\newcommand{\hlkwb}[1]{\textcolor[rgb]{0.69,0.353,0.396}{#1}}%
\newcommand{\hlkwc}[1]{\textcolor[rgb]{0.333,0.667,0.333}{#1}}%
\newcommand{\hlkwd}[1]{\textcolor[rgb]{0.737,0.353,0.396}{\textbf{#1}}}%

\usepackage{framed}
\makeatletter
\newenvironment{kframe}{%
 \def\at@end@of@kframe{}%
 \ifinner\ifhmode%
  \def\at@end@of@kframe{\end{minipage}}%
  \begin{minipage}{\columnwidth}%
 \fi\fi%
 \def\FrameCommand##1{\hskip\@totalleftmargin \hskip-\fboxsep
 \colorbox{shadecolor}{##1}\hskip-\fboxsep
     % There is no \\@totalrightmargin, so:
     \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}%
 \MakeFramed {\advance\hsize-\width
   \@totalleftmargin\z@ \linewidth\hsize
   \@setminipage}}%
 {\par\unskip\endMakeFramed%
 \at@end@of@kframe}
\makeatother

\definecolor{shadecolor}{rgb}{.97, .97, .97}
\definecolor{messagecolor}{rgb}{0, 0, 0}
\definecolor{warningcolor}{rgb}{1, 0, 1}
\definecolor{errorcolor}{rgb}{1, 0, 0}
\newenvironment{knitrout}{}{} % an empty environment to be redefined in TeX

\usepackage{alltt}
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}

\begin{document}

Here is a code chunk.

\begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{kframe}
\begin{alltt}
\hlnum{1} \hlopt{+} \hlnum{1}
\end{alltt}
\begin{verbatim}
## [1] 2
\end{verbatim}
\begin{alltt}
\hlstd{letters}
\end{alltt}
\begin{verbatim}
##  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q"
## [18] "r" "s" "t" "u" "v" "w" "x" "y" "z"
\end{verbatim}
\begin{alltt}
\hlkwd{chartr}\hlstd{(}\hlstr{"xie"}\hlstd{,} \hlstr{"XIE"}\hlstd{,} \hlkwd{c}\hlstd{(}\hlstr{"xie yihui"}\hlstd{,} \hlstr{"Yihui Xie"}\hlstd{))}
\end{alltt}
\begin{verbatim}
## [1] "XIE yIhuI" "YIhuI XIE"
\end{verbatim}
\begin{alltt}
\hlkwd{par}\hlstd{(}\hlkwc{mar} \hlstd{=} \hlkwd{c}\hlstd{(}\hlnum{4}\hlstd{,} \hlnum{4}\hlstd{,} \hlnum{0.2}\hlstd{,} \hlnum{0.2}\hlstd{))}
\hlkwd{plot}\hlstd{(}\hlkwd{rnorm}\hlstd{(}\hlnum{100}\hlstd{))}
\end{alltt}
\end{kframe}
\includegraphics[width=\maxwidth]{figure/foo} 

\end{knitrout}


You can also write inline expressions, e.g. $\pi=3.1416$, and \ensuremath{1.5987\times 10^{8}} is a big number.

\end{document}

FYI, I'm pretty new to LaTeX and knitr/sweave.

Best Answer

knitr has a few pretty straightforward ways of handling this.

Option 1: Using knit_child() with inline R code

Say your setup is like the following. In the same directory, you have:

graph.R

## ---- graph
library(ggplot2)
CarPlot <- ggplot() +
    stat_summary(data= mtcars,
                 aes(x = factor(gear),
                     y = mpg
                 ),
                 fun.y = "mean",
                 geom = "bar"
                 )
CarPlot

chapter1.Rnw

Hey, look, a graph (Figure~\ref{fig:graph})!

<<graph, echo=FALSE, message=FALSE, fig.lp='fig:', out.width='.5\\linewidth', fig.align='center', fig.cap="A graph", fig.pos='h!'>>=
@

main.Rnw

\documentclass{article}

\begin{document}

<<external-code, echo=FALSE, cache=FALSE>>=
read_chunk('./graph.R')
@

\Sexpr{knit_child('chapter1.Rnw')}

\end{document}

Then, you can knit the main.Rnw file and compile the resulting .tex file with either pdflatex or xelatex.

The output is:

enter image description here

Note that you can also read the external .R file from the child .Rnw file.

So, the following would have worked just as well.

chapter1-mod.Rnw

<<external-code, echo=FALSE, cache=FALSE>>=
read_chunk('./graph.R')
@

Hey, look, a graph (Figure~\ref{fig:graph})!

<<graph, echo=FALSE, message=FALSE, fig.lp='fig:', out.width='.5\\linewidth', fig.align='center', fig.cap="A graph", fig.pos='h!'>>=
@

main-mod.Rnw

\documentclass{article}

\begin{document}

\Sexpr{knit_child('chapter1-mod.Rnw')}

\end{document}

Option 2: Using chunk option child

Assuming you have graph.R and chapter1.Rnw from above in the same directory, then your main.Rnw should be:

\documentclass{article}

\begin{document}

<<external-code, echo=FALSE, cache=FALSE>>=
read_chunk('./graph.R')
@

<<child-demo, child='chapter1.Rnw'>>=
@

\end{document}

Note that you can also read the external .R file from within the child document in this case, too.

So, assuming you had graph.R and chapter1-mod.Rnw from above in the same directory, then your main-mod.Rnw file should be:

\documentclass{article}

\begin{document}

<<child-demo, child='chapter1-mod.Rnw'>>=
@

\end{document}
Related Question