Rmarkdown子文档没有检测到它们的“params”

时间:2018-03-25 11:28:19

标签: r r-markdown knitr

我有一个主Rmarkdown文档,我使用knitr的{​​{1}}选项将我的各个章节包含在其中。每章都使用rmarkdown parameters in its own YAML。 每章都可以单独编译,但是当放入这个主文档时,我会收到错误

child

我相信这是因为当孩子被编织时,knitr不会读取YAML中的参数(这是一个rmarkdown功能,而不是knitr功能)。

有什么方法可以让knitr使用这些吗?投入儿童文件是否存在“rmarkdown”?

object: 'params' not found

示例--- title: My thesis --- blah blah. # Introduction ```{r child='01-introduction.rmd'} ``` # Mathematical background ```{r child='02-mathsy-maths.rmd'} ```

01-introduction.rmd

1 个答案:

答案 0 :(得分:2)

As I understand knitr, when you knit a child document, this document is evaluated in the context (ie environment) of the parent document.

So, I see 4 solutions.

Set the params in the main document

With this solution, params are controlled inside the YAML front-matter of the main document. I think it is the natural solution.

---
title: My thesis
params:
  dataset: ABC
---

blah blah.

# Introduction

```{r child='01-introduction.rmd'}
```

# Mathematical background

```{r child='02-mathsy-maths.rmd'}
```

Assign the params in the global environment

With this solution, params are controlled with R code inside the main document.

---
title: My thesis
---

blah blah.

# Introduction
```{r set-params, include=FALSE}
params <- list(dataset = "ABC")
```

```{r child='01-introduction.rmd'}
```

# Mathematical background

```{r child='02-mathsy-maths.rmd'}
```

Retrieve params of the child document

With this solution, params are controlled inside each child document. It is a variant of the previous solution.
In the main document, child document's params are read using knitr::knit_params() and then assigned in the global environment.

---
title: My thesis
---

blah blah.

```{r def-assign-params, include=FALSE}
assign_params <- function(file) {
  text <- readLines(file)
  knit_params <- knitr::knit_params(text)
  params <<- purrr::map(knit_params, "value")
}
```

# Introduction

```{r, include=FALSE}
assign_params('01-introduction.rmd')
```

```{r child='01-introduction.rmd'}
```

# Mathematical background

```{r child='02-mathsy-maths.rmd'}
```

Use a (hacky) hook to assign params temporarily

Here, I define a hook for a new use.params chunk option: this solution extends the previous one. When use.params=TRUE is used, this hook is run for each chunk of the child document.
Note that with this solution, you cannot use params in inline code.

---
title: "Main document"
---

```{r hook-def, include=FALSE}
params_cache <- new.env(parent = emptyenv())

knitr::knit_hooks$set(use.params = function(before, options, envir) {
  if (before && options$use.params) {
    if (exists("params", envir = envir)) {
      params_cache$params <- envir$params
    }
    text <- readLines(knitr::current_input(dir = TRUE))
    knit_params <- knitr::knit_params(text)
    envir$params <- purrr::map(knit_params, "value")
  }
  if (!before && options$use.params) {
    if (exists("params", envir = params_cache)) {
      envir$params <- params_cache$params
      rm("params", envir = params_cache)
    } else {
      rm("params", envir = envir)
    }
  }
})
```

blah blah.

# Introduction

```{r child='01-introduction.rmd', use.params=TRUE}
```

# Mathematical background

```{r child='02-mathsy-maths.rmd', use.params=TRUE}
```