`bookdown` /`rmarkdown` /`knitr`:`YAML`标题中的子文档和路径定义

bal*_*lin 4 yaml r knitr r-markdown bookdown

我正在构建一个广泛使用子文档(via {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'
---
Run Code Online (Sandbox Code Playgroud)

使用此结构,访问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)
    
    Run Code Online (Sandbox Code Playgroud)

    其次是内部使用local_params而不是params.

  3. 使用类似于!R path.expand('data')YAML标头中定义参数的内容来就地扩展路径.虽然这种(或`为基础的等价物)的工作原理的data字段中的例子中,knitrING 失败路径中的情况下,作为R表达扩展,但作为一个字符的表示-和文字"path.expand('data')"显然不存在,作为一个路径.

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

rua*_*dhw 6

(通过隐式调用)的源代码r-yamlbookdown::render_book显示,通过使用expr标记解析相对路径,您可以非常轻松地解决选项3 :

params:
  submodule:
    value:
      intro:
        data_dir: !expr normalizePath('data')
Run Code Online (Sandbox Code Playgroud)

这将评估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"
Run Code Online (Sandbox Code Playgroud)

请注意,最好使用!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
Run Code Online (Sandbox Code Playgroud)