How to combine two RMarkdown (.Rmd) files into a single output?
Solution 1
August, 2018 update: This answer was written before the advent of bookdown, which is a more powerful approach to writing Rmarkdown based books. Check out the minimal bookdown example in @Mikey-Harper's answer!
When I want to break a large report into separate Rmd, I usually create a parent Rmd and include the chapters as children. This approach is easy for new users to understand, and if you include a table of contents (toc), it is easy to navigate between chapters.
report.Rmd
---
title: My Report
output:
pdf_document:
toc: yes
---
```{r child = 'chapter1.Rmd'}
```
```{r child = 'chapter2.Rmd'}
```
chapter1.Rmd
# Chapter 1
This is chapter 1.
```{r}
1
```
chapter2.Rmd
# Chapter 2
This is chapter 2.
```{r}
2
```
Build
rmarkdown::render('report.Rmd')
Which produces:
And if you want a quick way to create the chunks for your child documents:
rmd <- list.files(pattern = '*.Rmd', recursive = T)
chunks <- paste0("```{r child = '", rmd, "'}\n```\n")
cat(chunks, sep = '\n')
# ```{r child = 'chapter1.Rmd'}
# ```
#
# ```{r child = 'chapter2.Rmd'}
# ```
Solution 2
I'd recommend that people use the bookdown package for creating reports from multiple R Markdown files. It adds a lot of useful features like cross-referencing which are very useful for longer documents.
Adapting the example from @Eric, here is a minimal example of the bookdown setup. The main detail is that the main file has to be called index.Rmd
, and must include the additional YAML line site: bookdown::bookdown_site
:
index.Rmd
---
title: "A Minimal bookdown document"
site: bookdown::bookdown_site
output:
bookdown::pdf_document2:
toc: yes
---
01-intro.Rmd:
# Chapter 1
This is chapter 1.
```{r}
1
```
02-intro.Rmd:
# Chapter 2
This is chapter 2.
```{r}
2
```
If we Knit the index.Rmd
bookdown will merge all the files in the same directory in alphabetical order (this behaviour can be changed using an extra _bookdown.yml
file).
Once you get comfortable with this basic setup, it is easy to customise the bookdown document and output formats using additional configuration files i.e. _bookdown.yml
and _output.yml
Further Reading
- R Markdown: The definitive Guide: Chapter 11 provides a great overview of bookdown
- Authoring books with bookdown provides a comprehensive guide on bookdown, and recommended for more advanced details.
Solution 3
This worked for me:
Rmd_bind <-
function(dir = ".",
book_header = readLines(textConnection("---\ntitle: 'Title'\n---")))
{
old <- setwd(dir)
if(length(grep("book.Rmd", list.files())) > 0){
warning("book.Rmd already exists")
}
write(book_header, file = "book.Rmd", )
cfiles <- list.files(pattern = "*.Rmd", )
ttext <- NULL
for(i in 1:length(cfiles)){
text <- readLines(cfiles[i])
hspan <- grep("---", text)
text <- text[-c(hspan[1]:hspan[2])]
write(text, sep = "\n", file = "book.Rmd", append = T)
}
render("book.Rmd", output_format = "pdf_document")
setwd(old)
}
Imagine there's a better solution and would be nice to have something like this in rmarkdown or knitr packages.
Related videos on Youtube
Comments
-
RobinLovelace almost 2 years
I have two files in the same folder: chapter1.Rmd and chapter2.Rmd, with the following content:
chapter1.Rmd
--- title: "Chapter 1" output: pdf_document --- ## This is chapter 1. {#Chapter1} Next up: [chapter 2](#Chapter2)
chapter2.Rmd
--- title: "Chapter 2" output: pdf_document --- ## This is chapter 2. {#Chapter2} Previously: [chapter 1](#Chapter1)
How can I knit these so that they combine into a single pdf output?
Of course,
render(input = "chapter1.Rmd", output_format = "pdf_document")
works perfectly butrender(input = "chapter1.Rmd", input = "chapter2.Rmd", output_format = "pdf_document")
does not.Why do I want to do this? To break up a giant document into logical files.
I've used @hadley 's bookdown package to build latex from .Rmd but this seems like overkill for this particular task. Is there a simple solution using knitr/pandoc/linux command line I'm missing? Thanks.
-
Thomas almost 10 yearsWhy not just write natively in LaTeX? Seems like all the tools you need for this are built into LaTeX and the knitting process runs your document through a TeX engine anyway.
-
RobinLovelace almost 10 yearsYes I like latex and need to get into embedding code into it so that's a good plan B. Working on an R solution with read/writeLines function ATM because I believe Markdown is the user-friendly future! arxiv.org/abs/1402.1894 I.e. it's a philosophical decision: be the change you want to see in the world.
-
RobinLovelace almost 10 yearsAlso, writing as markdown reduces the barrier to entry to contributing. Eventually it will be LaTeX, but for the time being markdown is sufficient.
-
Ben over 8 yearshadley's bookdown is now being developed by @yihui and has had a lot of further work and useful documentation: rstudio.github.io/bookdown
-
-
Yihui Xie almost 10 yearsI think this is a reasonable solution, except you forgot a few parentheses (and indentation!! :)
-
Suat Atan PhD about 9 yearsIt works, yet i have 10 chapter. When i render the files, it goes up to 5th file. I can see all titles from PDF navigation panel but pages are not shown.
-
jangorecki almost 6 yearsis it possible to render nested Rmd files this way? how? I would like to have single Rmd for each element in a chapter.
-
Michael Harper almost 6 yearsbookdown generally recommends each file contains one chapter. However, it should be possible to split into separate files if desired. The easiest way would be to provide each file with a numeric index such as 1-1, 1-2, 1-3 etc.
-
Naveen Gabriel over 5 yearsI was trying to add appendix at the end which shows code for both document. How can i achieve ?
-
Michael Harper over 5 yearsThis seems like a distinct different question. You may want to open another question and provide a complete example which I will try my best to answer :)
-
Rasmus Larsen about 4 yearsClarification: Knit only previews the current document, while "Build book" builds it all.