knitr chapter bibliographies from .Rnw files?

Viewed 66

One can create chapter bibliographies using BibLaTeX and straight .tex files, as shown in this MWE:

% main.tex
\documentclass{report}
\usepackage{natbib}
\usepackage{chapterbib}

\begin{document}

\include{chap1}
\include{chap2}

\end{document}


% chap1.tex
\chapter{one chapter}

text~\cite{paper1}
text~\cite{paper2}

\bibliographystyle{plainnat}
\bibliography{biblio}


% chap2.tex
\chapter{another chapter}

text~\cite{paper2, paper3}

\bibliographystyle{plainnat}
\bibliography{biblio}


% biblio.bib
@Article{paper1,
  author =       {John Smith},
  title =        {A title},
  journal =      {A Journal},
  year =         {2010}
}
@Article{paper2,
  author =       {John Doe},
  title =        {A paper},
  journal =      {Another journal},
  year =         {2009}
}
@Article{paper3,
  author =       {Yuppie Networking},
  title =        {My paper},
  journal =      {The best journal},
  year =         {2000}
}

The above files can be successfully compiled with the following script:

% compile.bash
#!/bin/bash
pdflatex main.tex
for auxfile in chap*.aux
do
    bibtex `basename $auxfile .aux`
done
pdflatex main.tex
pdflatex main.tex

I wish to re-create the above functionality using knitr, BibLaTeX, and .Rnw files (not .tex files). Here's a small non-working example. (I know this example lacks R code chunks, but my use case will have R code chunks.)

% main.Rnw
\documentclass{report}
\usepackage{natbib}
\usepackage{chapterbib}

\begin{document}

\Sexpr{knitr::knit_child("chap1.Rnw")}
\Sexpr{knitr::knit_child("chap2.Rnw")}

\end{document}


% chap1.Rnw
\chapter{one chapter}

text~\cite{paper1}
text~\cite{paper2}

\bibliographystyle{plainnat}
\bibliography{biblio}


% chap2.Rnw
\chapter{another chapter}

text~\cite{paper2, paper3}

\bibliographystyle{plainnat}
\bibliography{biblio}


% knit_script.R
knitr::knit(input = "main.Rnw")


% compileRnw.bash
/usr/local/bin/Rscript knit_script.R

pdflatex main.tex
for auxfile in chap*.aux
do
    bibtex `basename $auxfile .aux`
done
pdflatex main.tex
pdflatex main.tex

When I run the compileRnw.bash script, the resulting document lacks bibliographies.

What should main.Rnw and compileRnw.bash look like to create a document with chapter bibliographies from the .Rnw files?

Thanks in advance for any help!

2 Answers

\Sexpr{knitr::knit_child("chap1.Rnw")} knits chap1.Rnw and returns the text content of chap1.tex instead of \include{chap1}. That's the difference between using .Rnw (your non-working example) and plain .tex (your first working example), which means there will not be a chap1.aux, because there is one and only one .tex output file, which is main.tex. You will only get one .aux file, too, which is main.aux. Then you need to run bibtex on main.aux instead of chap*.aux. Your shell script should be:

pdflatex main.tex
bibtex main.aux
pdflatex main.tex
pdflatex main.tex

In fact, you do not really need this shell script, because knitr::knit2pdf('main.Rnw') does all these steps automatically. Or equivalently, you can click the button "Compile PDF" on the RStudio toolbar if you use RStudio.

BTW, I don't know why you had to declare

\bibliographystyle{plainnat}
\bibliography{biblio}

in each chapter. That seems to be unnecessary. You can declare the bib style and database once in main.Rnw. If you duplicate them in each chapter, bibtex will complain, although it doesn't really hurt.

Thanks for this response!

A point of clarification.

  • In the examples, I use
\bibliographystyle{plainnat}
\bibliography{biblio}

in every chapter file, because I want a bibliography at the end of every chapter. To be specific, I want 2 bibliographies, one after Chapter 1 (containing only references from Chapter 1) and another after Chapter 2 (containing only references from Chapter 2).

  • Thanks to the answer from Yihui, I found that the following changes produce the output that I want.

In main.Rnw:

\documentclass{report}
\usepackage{natbib}
\usepackage{chapterbib}

\begin{document}

% \Sexpr{knitr::knit_child("chap1.Rnw")}
% \Sexpr{knitr::knit_child("chap2.Rnw")}

\include{chap1}
\include{chap2}

\end{document}

In knit_script.R:

# knit_script.R

# knitr::knit(input = "main.Rnw")

knitr::knit(input = "chap1.Rnw")
knitr::knit(input = "chap2.Rnw")
knitr::knit(input = "main.Rnw")

With those changes, I obtain a bibliography for each chapter.

Related