Use citation() in R Markdown to automatically generate a bibliography of R packages

I would like to cite the R packages used in a project but since they are quite numerous, I think it would be a good idea to create two separate reference sections: one with the references of my specific domain and one with the references for the R packages.

My first idea would be to check if I can export all the citations of the packages used at once in a .bib file, but I'm not sure that R Markdown can handle both the .bib file with the bibliography of papers specific to my domain and the .bib file for the R packages.

Since the functions citation() or toBibtex() generate Bibtex citations, I thought it might be possible to generate the reference section dedicated to the R packages with these functions directly in the .Rmd file. However, it does not seem possible to automatically format a reference when these commands are included in a chunk with R Markdown.

Here's a reproducible example of the thing I'm trying to do:

---
title: "Cite R packages"
author: ""
date: "01/02/2020"
output: pdf_document
bibliography: test.bib
---

This is a citation of a paper: @mayer2011.

# Bibliography {-}
\setlength{\parindent}{-0.2in}
\setlength{\leftskip}{0.2in}
\noindent
<div id="refs"></div>
```{r refmgr references, results="asis", echo=FALSE}
# Print
```
\setlength{\parindent}{0in}
\setlength{\leftskip}{0in}
\setlength{\parskip}{0pt}

# Bibliography for R packages {-}
```{r}
citation("dplyr")
toBibtex(citation("dplyr"))
```

and here's the content of test.bib:

@article{mayer2011,
  title = {Notes on {{CEPII}}'s {{Distances Measures}}: {{The GeoDist Database}}},
  shorttitle = {Notes on {{CEPII}}'s {{Distances Measures}}},
  journal = {SSRN Electronic Journal},
  doi = {10.2139/ssrn.1994531},
  author = {Mayer, Thierry and Zignago, Soledad},
  year = {2011}
}

Any idea about how to easily include the references of the R packages?

Also asked on SO

1 Like

Hi @bretauv,

In fact, you can provide multiple .bib files to the RMarkdown document. This is not an issue. There are also a few convenience functions inside the knitr package that makes exporting a bunch of package citations very simple. For example:

knitr::write_bib(c('knitr', 'rmarkdown'), file = 'packages.bib')

This will save a file called packages.bib with all the relevant entries for those two packages. If you exclude the file argument, the bib entries are printed to the console and you can manually use them in any way you like.

Then, in your R Markdown document, add more .bib files like this:

---
title: "Cite R packages"
author: ""
date: "01/02/2020"
output: pdf_document
bibliography: [test.bib, packages.bib]
---

Here is a sweet sentence that references my favourite author [@mayer2011], and also gives credit to the R packages [@R-knitr; @R-rmarkdown].
1 Like

hi @mattwarkentin, thanks for your answer but this does not solve the problem of separation between the references for a specific domain and the references for the R packages. Here, there is not interest in having two .bib files (it would be the same result if we merge the two .bib files).

The best thing would be to have a "marker" for each reference saying "this reference goes in the first bibliography, this other reference goes in the R packages bibliography, etc." but I don't know if it possible to do such a thing, hence my question about automatically converting the output of citation into clean references.

Ahh, I see. You want to have separate reference pages in your rendered document for domain and package-specific references?

@mattwarkentin yes exactly, it is in the first paragraph of my post, maybe I should have made it clearer :wink:

Yes, sorry. I thought you meant two bibliography files, not two reference sections.

@mattwarkentin I edited my post, it should be better

Have you considered using child documents?

@mattwarkentin I've never used child documents, could you add an example so that I can see what you have in mind?

On second thought I am not sure if this would be the best approach. It is very unorthodox to provide in-text citations for domain-specific texts and packages, but separate reference pages, so I am trying to think-through how this could possibly be done in a reliable way.

@mattwarkentin the thing is I want to thank the creators of the packages I use by adding them in the reference section but I'm afraid that mixing the references for the packages with the domain-specific references makes it unclear, especially because few people use R in my university.

For example, suppose that I want to put 40 packages in the reference section, it adds 40 references to the domain-specific references (which are also quite numerous), making it harder for a reader to quickly see what papers I used. This is why I think having two separate reference sections would be more convenient. It is maybe unorthodox but it is the best way I can think of.

PS: I'm not completely limited in terms of organization of the document since this is not destined to be a peer-reviewed article for example, in which the page layout is very controlled.

the easier workaround is probably to create a second Rmd file with only the R citation and then copy-paste the bibliography you get from there, this works only if you do all your R citation into one part of the document, though.
Reference lists tend to be quite difficult to sort apparently

1 Like

@jcolomb thanks but how is this different from the first answer?

It's not really different, but indeed is it tricky to sort reference lists non-manually. And this is why I thought child documents might be the solution even if its not the perfect one.

@mattwarkentin it would help me if you had an example, because I really don't see what your solution / workaround is (I've never used child documents)

Okay, here is another attempt I've made. For now, this is purely done in LaTeX, but if this looks correct to you, it can be turned into a TeX template for R Markdown.

Using biblatex you can declare bibliographic categories and add entries to each category. In the end, you can print them separately as reference pages

Here is the TeX code:.

\documentclass{article}
\usepackage[style=authoryear]{biblatex}
\addbibresource{/Users/Matt/Desktop/refs.bib}

\DeclareBibliographyCategory{R}
\addtocategory{R}{R-ggplot2}

\DeclareBibliographyCategory{domain}
\addtocategory{domain}{eddelbuettel2011rcpp}

\begin{document}

Here is a great sentence about plotting (\cite{R-ggplot2}), which also has some domain content (\cite{eddelbuettel2011rcpp}).

\section*{Domain References}
\printbibliography[category=domain,heading=none]

\section*{R References}
\printbibliography[category=R,heading=none]
\end{document}

I rendered this by running, in order:

pdflatex filename
biber filename
pdflatex filename

It produces this: filename.pdf (60.8 KB)

@mattwarkentin this is exactly the output I want. That means that when I know the complete lists of packages I used, I turn this list into a .bib file with knitr::write_bib, then I divide the citations between the category R and the category domain, and finally I generate two separate references sections.

I will search how to turn this into a TeX template for R Markdown, but if you know how to do so, please show me because I never transformed TeX in R Markdown.

Anyway, thanks a lot

I have done a fair amount of work creating TeX templates for RMarkdown. So we can go that route if need be. And I would be happy to show you how its done.

However, I was thinking about this some more and I actually think we can pull this off without having to template anything. Let me make an attempt at doing this and lets see how it goes.

Alright, this should work. This is an example of a working Rmd file:

---
title: "Untitled"
output: 
  pdf_document:
    template: template-sep-refs.tex
    citation_package: biblatex
    includes:
      in_header: header.tex
bibliography: [refs.bib]
---

Here is a domain-specific reference [@eddelbuettel2011rcpp], and here is an R reference [@R-ggplot2]. 

Here is another citation [@R-knitr], and it will show up in both reference lists.

# Domain References {-}

\printbibliography[category=domain,heading=none]

# R References {-}

\printbibliography[category=R,heading=none]

You can customize the different reference groups in the file called header.tex which should be in the same location as the Rmd file. It contains:

\usepackage[style=numeric,backend=biber]{biblatex}
\DeclareBibliographyCategory{domain}
\DeclareBibliographyCategory{R}
\addtocategory{domain}{eddelbuettel2011rcpp, R-knitr}
\addtocategory{R}{R-ggplot2, R-knitr}

Play with this as you wish to choose the citation style, and also to set up the different categories, and which citations belong to which category. The \addtocategory function can take a comma-separated list of IDs like \addtocategory{R}{ID1, ID2, ID3, ...}. Note: A bib ID can belong to more than one category, if you want to it to show up in both reference lists, for example.

Lastly, you need to template file (template-sep-refs.tex). This is the default LaTeX template for R Markdown (found here), I just commented out some lines (lines 380-388) to make this work. Place this in the same location as the Rmd file.

% Options for packages loaded elsewhere
\PassOptionsToPackage{unicode$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref}
\PassOptionsToPackage{hyphens}{url}
$if(colorlinks)$
\PassOptionsToPackage{dvipsnames,svgnames*,x11names*}{xcolor}
$endif$
$if(dir)$
$if(latex-dir-rtl)$
\PassOptionsToPackage{RTLdocument}{bidi}
$endif$
$endif$
%
\documentclass[
$if(fontsize)$
  $fontsize$,
$endif$
$if(lang)$
  $babel-lang$,
$endif$
$if(papersize)$
  $papersize$paper,
$endif$
$if(beamer)$
  ignorenonframetext,
$if(handout)$
  handout,
$endif$
$if(aspectratio)$
  aspectratio=$aspectratio$,
$endif$
$endif$
$for(classoption)$
  $classoption$$sep$,
$endfor$
]{$documentclass$}
$if(beamer)$
$if(background-image)$
\usebackgroundtemplate{%
  \includegraphics[width=\paperwidth]{$background-image$}%
}
$endif$
\usepackage{pgfpages}
\setbeamertemplate{caption}[numbered]
\setbeamertemplate{caption label separator}{: }
\setbeamercolor{caption name}{fg=normal text.fg}
\beamertemplatenavigationsymbols$if(navigation)$$navigation$$else$empty$endif$
$for(beameroption)$
\setbeameroption{$beameroption$}
$endfor$
% Prevent slide breaks in the middle of a paragraph
\widowpenalties 1 10000
\raggedbottom
$if(section-titles)$
\setbeamertemplate{part page}{
  \centering
  \begin{beamercolorbox}[sep=16pt,center]{part title}
    \usebeamerfont{part title}\insertpart\par
  \end{beamercolorbox}
}
\setbeamertemplate{section page}{
  \centering
  \begin{beamercolorbox}[sep=12pt,center]{part title}
    \usebeamerfont{section title}\insertsection\par
  \end{beamercolorbox}
}
\setbeamertemplate{subsection page}{
  \centering
  \begin{beamercolorbox}[sep=8pt,center]{part title}
    \usebeamerfont{subsection title}\insertsubsection\par
  \end{beamercolorbox}
}
\AtBeginPart{
  \frame{\partpage}
}
\AtBeginSection{
  \ifbibliography
  \else
    \frame{\sectionpage}
  \fi
}
\AtBeginSubsection{
  \frame{\subsectionpage}
}
$endif$
$endif$
$if(beamerarticle)$
\usepackage{beamerarticle} % needs to be loaded first
$endif$
$if(fontfamily)$
\usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$}
$else$
\usepackage{lmodern}
$endif$
$if(linestretch)$
\usepackage{setspace}
$endif$
\usepackage{amssymb,amsmath}
\usepackage{ifxetex,ifluatex}
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
  \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc}
  \usepackage[utf8]{inputenc}
  \usepackage{textcomp} % provide euro and other symbols
\else % if luatex or xetex
$if(mathspec)$
  \ifxetex
    \usepackage{mathspec}
  \else
    \usepackage{unicode-math}
  \fi
$else$
  \usepackage{unicode-math}
$endif$
  \defaultfontfeatures{Scale=MatchLowercase}
  \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}
$if(mainfont)$
  \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$}
$endif$
$if(sansfont)$
  \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$}
$endif$
$if(monofont)$
  \setmonofont[$for(monofontoptions)$$monofontoptions$$sep$,$endfor$]{$monofont$}
$endif$
$for(fontfamilies)$
  \newfontfamily{$fontfamilies.name$}[$for(fontfamilies.options)$$fontfamilies.options$$sep$,$endfor$]{$fontfamilies.font$}
$endfor$
$if(mathfont)$
$if(mathspec)$
  \ifxetex
    \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
  \else
    \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
  \fi
$else$
  \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$}
$endif$
$endif$
$if(CJKmainfont)$
  \ifxetex
    \usepackage[space]{xeCJK}
    \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$}
  \fi
$endif$
$if(luatexjapresetoptions)$
  \ifluatex
    \usepackage[$for(luatexjapresetoptions)$$luatexjapresetoptions$$sep$,$endfor$]{luatexja-preset}
  \fi
$endif$
$if(CJKmainfont)$
  \ifluatex
    \usepackage[$for(luatexjafontspecoptions)$$luatexjafontspecoptions$$sep$,$endfor$]{luatexja-fontspec}
    \setmainjfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$}
  \fi
$endif$
\fi
$if(beamer)$
$if(theme)$
\usetheme[$for(themeoptions)$$themeoptions$$sep$,$endfor$]{$theme$}
$endif$
$if(colortheme)$
\usecolortheme{$colortheme$}
$endif$
$if(fonttheme)$
\usefonttheme{$fonttheme$}
$endif$
$if(mainfont)$
\usefonttheme{serif} % use mainfont rather than sansfont for slide text
$endif$
$if(innertheme)$
\useinnertheme{$innertheme$}
$endif$
$if(outertheme)$
\useoutertheme{$outertheme$}
$endif$
$endif$
% Use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
\IfFileExists{microtype.sty}{% use microtype if available
  \usepackage[$for(microtypeoptions)$$microtypeoptions$$sep$,$endfor$]{microtype}
  \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
}{}
$if(indent)$
$else$
\makeatletter
\@ifundefined{KOMAClassName}{% if non-KOMA class
  \IfFileExists{parskip.sty}{%
    \usepackage{parskip}
  }{% else
    \setlength{\parindent}{0pt}
    \setlength{\parskip}{6pt plus 2pt minus 1pt}}
}{% if KOMA class
  \KOMAoptions{parskip=half}}
\makeatother
$endif$
$if(verbatim-in-note)$
\usepackage{fancyvrb}
$endif$
\usepackage{xcolor}
\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}}
\hypersetup{
$if(title-meta)$
  pdftitle={$title-meta$},
$endif$
$if(author-meta)$
  pdfauthor={$author-meta$},
$endif$
$if(lang)$
  pdflang={$lang$},
$endif$
$if(subject)$
  pdfsubject={$subject$},
$endif$
$if(keywords)$
  pdfkeywords={$for(keywords)$$keywords$$sep$, $endfor$},
$endif$
$if(colorlinks)$
  colorlinks=true,
  linkcolor=$if(linkcolor)$$linkcolor$$else$Maroon$endif$,
  filecolor=$if(filecolor)$$filecolor$$else$Maroon$endif$,
  citecolor=$if(citecolor)$$citecolor$$else$Blue$endif$,
  urlcolor=$if(urlcolor)$$urlcolor$$else$Blue$endif$,
$else$
  hidelinks,
$endif$
  pdfcreator={LaTeX via pandoc}}
\urlstyle{same} % disable monospaced font for URLs
$if(verbatim-in-note)$
\VerbatimFootnotes % allow verbatim text in footnotes
$endif$
$if(geometry)$
$if(beamer)$
\geometry{$for(geometry)$$geometry$$sep$,$endfor$}
$else$
\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
$endif$
$endif$
$if(beamer)$
\newif\ifbibliography
$endif$
$if(listings)$
\usepackage{listings}
\newcommand{\passthrough}[1]{#1}
\lstset{defaultdialect=[5.3]Lua}
\lstset{defaultdialect=[x86masm]Assembler}
$endif$
$if(lhs)$
\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
$endif$
$if(highlighting-macros)$
$highlighting-macros$
$endif$
$if(tables)$
\usepackage{longtable,booktabs}
$if(beamer)$
\usepackage{caption}
% Make caption package work with longtable
\makeatletter
\def\fnum@table{\tablename~\thetable}
\makeatother
$else$
% Correct order of tables after \paragraph or \subparagraph
\usepackage{etoolbox}
\makeatletter
\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{}
\makeatother
% Allow footnotes in longtable head/foot
\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}}
\makesavenoteenv{longtable}
$endif$
$endif$
$if(graphics)$
\usepackage{graphicx}
\makeatletter
\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi}
\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi}
\makeatother
% Scale images if necessary, so that they will not overflow the page
% margins by default, and it is still possible to overwrite the defaults
% using explicit options in \includegraphics[width, height, ...]{}
\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio}
% Set default figure placement to htbp
\makeatletter
\def\fps@figure{htbp}
\makeatother
$endif$
$if(links-as-notes)$
% Make links footnotes instead of hotlinks:
\DeclareRobustCommand{\href}[2]{#2\footnote{\url{#1}}}
$endif$
$if(strikeout)$
\usepackage[normalem]{ulem}
% Avoid problems with \sout in headers with hyperref
\pdfstringdefDisableCommands{\renewcommand{\sout}{}}
$endif$
\setlength{\emergencystretch}{3em} % prevent overfull lines
\providecommand{\tightlist}{%
  \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
$if(numbersections)$
\setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$}
$else$
\setcounter{secnumdepth}{-\maxdimen} % remove section numbering
$endif$
$if(beamer)$
$else$
$if(block-headings)$
% Make \paragraph and \subparagraph free-standing
\ifx\paragraph\undefined\else
  \let\oldparagraph\paragraph
  \renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}}
\fi
\ifx\subparagraph\undefined\else
  \let\oldsubparagraph\subparagraph
  \renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}}
\fi
$endif$
$endif$
$if(pagestyle)$
\pagestyle{$pagestyle$}
$endif$
$for(header-includes)$
$header-includes$
$endfor$
$if(lang)$
\ifxetex
  % Load polyglossia as late as possible: uses bidi with RTL langages (e.g. Hebrew, Arabic)
  \usepackage{polyglossia}
  \setmainlanguage[$polyglossia-lang.options$]{$polyglossia-lang.name$}
$for(polyglossia-otherlangs)$
  \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$}
$endfor$
\else
  \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel}
$if(babel-newcommands)$
  $babel-newcommands$
$endif$
\fi
$endif$
$if(dir)$
\ifxetex
  % Load bidi as late as possible as it modifies e.g. graphicx
  \usepackage{bidi}
\fi
\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
  \TeXXeTstate=1
  \newcommand{\RL}[1]{\beginR #1\endR}
  \newcommand{\LR}[1]{\beginL #1\endL}
  \newenvironment{RTL}{\beginR}{\endR}
  \newenvironment{LTR}{\beginL}{\endL}
\fi
$endif$
$if(natbib)$
\usepackage[$natbiboptions$]{natbib}
\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$}
$endif$
$if(biblatex)$
\usepackage[$if(biblio-style)$style=$biblio-style$,$endif$$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$]{biblatex}
$for(bibliography)$
\addbibresource{$bibliography$}
$endfor$
$endif$
$if(csl-refs)$
\newlength{\cslhangindent}
\setlength{\cslhangindent}{1.5em}
\newenvironment{cslreferences}%
  {$if(csl-hanging-indent)$\setlength{\parindent}{0pt}%
  \everypar{\setlength{\hangindent}{\cslhangindent}}\ignorespaces$endif$}%
  {\par}
$endif$

$if(title)$
\title{$title$$if(thanks)$\thanks{$thanks$}$endif$}
$endif$
$if(subtitle)$
$if(beamer)$
$else$
\usepackage{etoolbox}
\makeatletter
\providecommand{\subtitle}[1]{% add subtitle to \maketitle
  \apptocmd{\@title}{\par {\large #1 \par}}{}{}
}
\makeatother
$endif$
\subtitle{$subtitle$}
$endif$
\author{$for(author)$$author$$sep$ \and $endfor$}
\date{$date$}
$if(beamer)$
$if(institute)$
\institute{$for(institute)$$institute$$sep$ \and $endfor$}
$endif$
$if(titlegraphic)$
\titlegraphic{\includegraphics{$titlegraphic$}}
$endif$
$if(logo)$
\logo{\includegraphics{$logo$}}
$endif$
$endif$

\begin{document}
$if(has-frontmatter)$
\frontmatter
$endif$
$if(title)$
$if(beamer)$
\frame{\titlepage}
$else$
\maketitle
$endif$
$if(abstract)$
\begin{abstract}
$abstract$
\end{abstract}
$endif$
$endif$

$for(include-before)$
$include-before$

$endfor$
$if(toc)$
$if(toc-title)$
\renewcommand*\contentsname{$toc-title$}
$endif$
$if(beamer)$
\begin{frame}[allowframebreaks]
$if(toc-title)$
  \frametitle{$toc-title$}
$endif$
  \tableofcontents[hideallsubsections]
\end{frame}
$else$
{
$if(colorlinks)$
\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$$endif$}
$endif$
\setcounter{tocdepth}{$toc-depth$}
\tableofcontents
}
$endif$
$endif$
$if(lot)$
\listoftables
$endif$
$if(lof)$
\listoffigures
$endif$
$if(linestretch)$
\setstretch{$linestretch$}
$endif$
$if(has-frontmatter)$
\mainmatter
$endif$
$body$

$if(has-frontmatter)$
\backmatter
$endif$
$if(natbib)$
$if(bibliography)$
$if(biblio-title)$
$if(has-chapters)$
\renewcommand\bibname{$biblio-title$}
$else$
\renewcommand\refname{$biblio-title$}
$endif$
$endif$
$if(beamer)$
\begin{frame}[allowframebreaks]{$biblio-title$}
  \bibliographytrue
$endif$
 \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$}
$if(beamer)$
 \end{frame}
$endif$

$endif$
$endif$

%% $if(biblatex)$
%% $if(beamer)$
%% \begin{frame}[allowframebreaks]{$biblio-title$}
%%   \bibliographytrue
%%   \printbibliography[heading=none]
%% \end{frame}
%% $else$
%% \printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$
%% $endif$

$endif$
$for(include-after)$
$include-after$

$endfor$
\end{document}
1 Like

@mattwarkentin this works and the output is perfect! For your information, a great answer was posted today on StackOverflow with a different method. You should take a look at it both because it is interesting and because I think it is possible to use the function created there to generate the .bib file for R packages with your answer.

Thanks again for having taken this time to make a great solution