`bookdown` /`rmarkdown` /`knitr`:`YAML`标题

时间:2017-12-05 13:12:39

标签: r yaml knitr r-markdown bookdown

我正在构建一个广泛使用子文档的报告基础结构(通过{r, child = 'somedir/child_doc.Rmd'})并通过主文档的params标题中的YAML字典进行参数化。一个例子可能是:

---
title: Project Report
subtitle: POIGNANT DESCRIPTION OF THE WORK AT HAND
date: '`r format(Sys.time(), "%d %B, %Y")`'
output:
  bookdown::pdf_document2:
    template: ~
    toc: yes
    toc_depth: 2
colorlinks: yes
fontsize: 11pt
documentclass: scrartcl
geometry: margin=1in, a4paper
params:
  submodule:
    value:
      intro:
        data_dir: 'data'
---

使用此结构,访问data_dir会出现问题,因为主文档和子文档的工作目录不同,因此相对路径定义也有所不同。方法是:

  1. 在定义data_dir时使用绝对/扩展路径名。 快速变得长/笨重。

  2. params对象的后处理,以扩展主文档中的路径。从params块内部访问时R是不可变的,这只能以不优雅的方式解决:

    ```{r params-processing, include = FALSE}
    local_params <- params
    local_params$submodule$intro$data_dir <- path.expand(local_params$submodule$intro$data_dir)
    

    其次是内部使用local_params代替params

  3. !R path.expand('data')标题中定义参数时,使用YAML之类的内容扩展路径。虽然这个(或基于`的等价物)适用于示例中的data字段,但knitr 在路径案例中失败,因为R表达式是已展开但用作字符表示 - 文字"path.expand('data')"显然不存在作为路径。

  4. 我很欣赏有关如何解决这个问题的任何提示 - 尤其是3.是否可以实现......

1 个答案:

答案 0 :(得分:5)

source code of r-yaml(由bookdown::render_book隐式调用)表明您可以通过使用expr标记解析相对路径,轻松地解决选项3:

params:
  submodule:
    value:
      intro:
        data_dir: !expr normalizePath('data')

这将评估YAML中的R表达式,不需要任何进一步处理。

data_dir: !r normalizePath('data')也是可接受的语法,由knitr处理。不幸的是,只有!R`r,你试过的两个都被解释了。

我还建议使用normalizePath,因为它返回给定任何相对目录的绝对路径。您使用path.expand的示例仅执行波浪线扩展,因此对'data'等本地相对路径没有影响。 normalizePath实际上是path.expand作为第一步。

只需照常访问完全展开的路径

```{r params-processing}
print(params$submodule$intro$data_dir)
```
## $value
## [1] "/Users/user_name/full_path_to_book/my_book/data"
##
## $expr
## [1] "normalizePath('data')"
##
## attr(,"class")
## [1] "knit_param_expr"

请注意,最好使用!r看到r-yaml行为可能会因为当前发出警告而发生变化:

Warning message:
In yaml.load(readLines(con), error.label = error.label, ...) :
  R expressions in yaml.load will not be auto-evaluated by default in the near future