`bookdown`/`rmarkdown`/`knitr`:`YAML` 标头中的子文档和路径定义 [英] `bookdown`/`rmarkdown`/`knitr`: Child documents and path definition in `YAML` headers

查看:48
本文介绍了`bookdown`/`rmarkdown`/`knitr`:`YAML` 标头中的子文档和路径定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm building a reporting infrastructure that makes extensive use of child documents (via {r, child = 'somedir/child_doc.Rmd'}) AND is parametrized through the params dictionary in the YAML header of the master document. An example might be:

---
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 会出现问题,因为主文档和子文档的工作目录不同,因此相对路径定义也不同.出路是:

Using this structure, accessing data_dir becomes problematic as the working directory differs for the master and child documents and thus relative path definitions also diverge. Ways out are:

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

  1. Usage of absolute/expanded path names in defining data_dir. Gets long/unwieldy quickly.

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

Postprocessing of the params object to expand the path within the master document. As params is immutable when accessed from within R chunks, this can only be solved in an inelegant manner:

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

Followed by internal usage of local_params instead of params.

YAML 标头中定义参数时,使用类似 !R path.expand('data') 的内容就地扩展路径.虽然这(或基于 `-based 的等效项)适用于示例中的 data 字段,knitring fails 在路径案例中作为 R 表达式没有扩展而是用作字符表示 - 并且文字 "path.expand('data')" 显然不存在作为路径.

In-place expansion of the path using something like !R path.expand('data') when defining the parameter in the YAML header. While this (or the `-based equivalent) works for the data field in the example, knitring fails in the path case as the R expression is not expanded but used as a character-representation - and literal "path.expand('data')" obviously doesn't exist as a path.

我很感激关于如何漂亮地解决这个问题的任何提示 - 特别是 3. 是否可以工作......

I'd appreciate any hints on how to solve this prettily - especially whether 3. can be made work ...

推荐答案

r-yaml 的源代码(由 bookdown::render_book 隐式调用)表明您可以通过解析很容易地解决选项 3带有 expr 标签的相对路径:

The source code of r-yaml (which is implicitly called by bookdown::render_book) shows you can solve option 3 fairly easily by parsing the relative path with the expr tag:

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

这会计算 YAML 中的 R 表达式,不需要任何进一步处理.

This evaluates the R expression in the YAML and doesn't require any further processing.

data_dir: !r normalizePath('data') 也是可接受的语法,由 knitr.不幸的是,您尝试过的两个 !R`r 都没有被解释.

data_dir: !r normalizePath('data') is also acceptable syntax which is processed by knitr. Unfortunately just neither of !R or `r, the two you tried, are interpreted.

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

I also suggest using normalizePath instead as it returns an absolute path given any relative directory. Your example of using path.expand only performs tilde expansion so has no effect on a local relative path such as 'data'. normalizePath actually calls path.expand as a first step.

只需像往常一样访问完全展开的路径

Simply access the fully expanded path as usual

```{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 行为可能会改变,因为它当前会抛出警告:

Note, it might be best to use !r seeing as the r-yaml behaviour may change as it currently throws a warning:

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

这篇关于`bookdown`/`rmarkdown`/`knitr`:`YAML` 标头中的子文档和路径定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆