如何将两个RMarkdown(.Rmd)文件合并为一个输出?

133

我在同一个文件夹中有两个文件:chapter1.Rmd和chapter2.Rmd,它们的内容如下:

chapter1.Rmd

---
title: "Chapter 1"
output: pdf_document
---

## This is chapter 1. {#Chapter1}

Next up: [chapter 2](#Chapter2)

第二章.Rmd

---
title: "Chapter 2"
output: pdf_document
---

## This is chapter 2. {#Chapter2}

Previously: [chapter 1](#Chapter1)

如何将它们编织在一起形成单个的PDF输出?

当然,render(input = "chapter1.Rmd", output_format = "pdf_document") 可以完美地工作,但是 render(input = "chapter1.Rmd", input = "chapter2.Rmd", output_format = "pdf_document") 则不行。

我为什么要这样做?是为了将一个巨大的文档拆分成逻辑文件。

我已经使用了@hadley的bookdown包从.Rmd构建LaTeX,但这似乎对于这个特定的任务来说太过浩大。是否有一个使用knitr/pandoc/linux命令行的简单解决方案我错过了?谢谢。


3
为什么不直接用LaTeX原生编写呢?似乎LaTeX内置了所有所需工具,而且编织过程也会通过TeX引擎运行您的文档。 - Thomas
19
我喜欢使用 LaTeX,并计划将代码嵌入其中,这是一个不错的备选方案。我正在使用read/writeLines函数研究 R 解决方案,因为我相信 Markdown 是用户友好的未来!http://arxiv.org/abs/1402.1894 这是一种哲学决定:要成为你想在世界上看到的变化。 - RobinLovelace
3
同样,采用Markdown写作可降低投稿门槛。虽然最终会转向LaTeX,但目前使用Markdown已经足够。 - RobinLovelace
5
Hadley的Bookdown现在由@yihui开发,并且有很多进一步的工作和有用的文档:http://rstudio.github.io/bookdown/ - Ben
3个回答

188

2018年8月更新:这个答案是在bookdown出现之前编写的,后者是一种更强大的基于Rmarkdown编写书籍的方法。请查看@Mikey-Harper的答案中提供的最小bookdown示例!

当我想要将一个大报告分成多个Rmd文件时,我通常会创建一个父级Rmd并将章节作为子级包含进去。这种方法对新用户来说很容易理解,如果您包括目录(toc),则很容易在章节之间进行导航。

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
```

构建

rmarkdown::render('report.Rmd')

这将产生如下结果: 我的报告

如果您希望快速为子文档创建块:

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'}
# ```

它可以工作,但我有10个章节。当我渲染文件时,它只到第5个文件。我可以从PDF导航面板中看到所有标题,但页面未显示。 - Suat Atan PhD

46
我建议人们使用bookdown包从多个R Markdown文件创建报告。它添加了许多有用的功能,如交叉引用,对于较长的文档非常有用。
根据@Eric的示例进行调整,这是bookdown设置的最小示例。主要细节是主文件必须称为index.Rmd,并且必须包括附加的YAML行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
```

如果我们编织index.Rmdbookdown将按字母顺序合并同一目录中的所有文件(可以使用额外的_bookdown.yml文件更改此行为)。

enter image description here

一旦您熟悉了这个基本设置,就可以使用其他配置文件(即_bookdown.yml_output.yml)轻松定制bookdown文档和输出格式。

进一步阅读


这种方式是否可以呈现嵌套的Rmd文件?如何实现?我想为_chapter_中的每个元素拥有单独的Rmd。 - jangorecki
bookdown通常建议每个文件包含一个章节。但是,如果需要,可以将其拆分为单独的文件。最简单的方法是为每个文件提供一个数字索引,例如1-1、1-2、1-3等。 - Michael Harper
我试图在文档末尾添加附录,其中显示了两个文档的代码。我该如何实现? - Naveen Gabriel
这似乎是一个完全不同的问题。您可能想打开另一个问题并提供一个完整的示例,我会尽力回答 :) - Michael Harper
澄清:Knit 仅预览当前文档,而“构建书籍”则构建整个文档。 - Rasmus Larsen

5
这对我有用:

这适用于我:

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)
    }

想象一下,如果rmarkdown或knitr这些包中有类似的更好的解决方案,将是非常不错的。


9
我认为这个解决方案是合理的,只是你忘记了一些括号(还有缩进!! :) - Yihui Xie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接