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'
---
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:
Usage of absolute/expanded path names in defining data_dir
. Gets long/unwieldy quickly.
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)
Followed by internal usage of local_params
instead of params
.
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, knitr
ing 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.
I'd appreciate any hints on how to solve this prettily - especially whether 3. can be made work ...
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')
This evaluates the R expression in the YAML and doesn't require any further processing.
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.
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"
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With