5

I am creating a quarto book project in RStudio to render an html document. I need to specify some parameters in the yml file but the qmd file returns "object 'params' not found". Using knitR.

I use the default yml file where I have added params under the book tag

project:
  type: book

book:
  title: "Params_TEst"
  author: "Jane Doe"
  date: "15/07/2022"
  params:
    pcn: 0.1
  chapters:
    - index.qmd
    - intro.qmd
    - summary.qmd
    - references.qmd

bibliography: references.bib

format:
  html:
    theme: cosmo
  pdf:
    documentclass: scrreprt

editor: visual

and the qmd file looks like this

# Preface {.unnumbered}

This is a Quarto book.

To learn more about Quarto books visit <https://quarto.org/docs/books>.

```{r}
1 + 1
params$pcn

When I render the book, or preview the book in Rstudio the error I receive is:

Quitting from lines 8-10 (index.qmd) Error in eval(expr, envir, enclos) : object 'params' not found Calls: .main ... withVisible -> eval_with_user_handlers -> eval -> eval

I have experimented placing the params line in the yml in different places but nothing works so far.

Could anybody help?

Philip
  • 335
  • 3
  • 11
  • Placing the params in `index.qmd` YAML header should work. Did you try that ? I don't know if setting params in `_quarto.yml` works... – cderv Jul 15 '22 at 11:47
  • 1
    Thank you yes, specifying a parameter in index.qmd like this works: --- params: pcn: 0.1 --- # Preface {.unnumbered} This is a Quarto book. To learn more about Quarto books visit . ```{r} 1 + 1 params$pcn However it would be better to supply the params in the yml file somehow as then the parameter could be shared across all qmd files which would be useful to a lot of people. – Philip Jul 15 '22 at 13:24
  • 1
    Yes please open a feature request for this ! thank you – cderv Jul 21 '22 at 10:10

2 Answers2

2

For multi-page renders, e.g. quarto books, you need to add the YAML to each page, not in the _quarto.yml file

So in your case, each of the chapters that calls a parameter needs a YAML header, like index.qmd, intro.qmd, and summary.qmd, but perhaps not references.qmd.

The YAML header should look just like it does in a standard Rmd. So for example, your index.qmd would look like this:

---
  params:
    pcn: 0.1
---

# Preface {.unnumbered}

This is a Quarto book.

To learn more about Quarto books visit <https://quarto.org/docs/books>.

```{r}
1 + 1
params$pcn

But, what if you need to change the parameter and re-render? Then simply pass new parameters to the quarto_render function

quarto::quarto_render(input = here::here("quarto"), #expecting a dir to render
                      output_format = "html", #output dir is set in _quarto.yml
                      cache_refresh = TRUE, 
                      execute_params = list(pcn = 0.2))
Hirschey
  • 95
  • 5
1

For now, this only seems to work if you add the parameters to each individual page front-matter YAML.

If you have a large number of pages and need to keep parameters centralized, a workaround is to run a preprocessing script that replaces the parameters in all pages. To add a preprocessing script, add the key pre-render to your _quarto.yml file. The Quarto website has detailed instructions.

For example, if you have N pages named index<N>.qmd, you could have a placeholder in the YML of each page:

---
title: This is chapter N
yourparamplaceholder
---

Your pre-render script could replace yourparamplaceholder with the desired parameters. Here's an example Python script:

for filename in os.listdir(dir):
  if filename.endswith(".qmd"):
    with open(filename, "r") as f:
      txt = f.read()
      f.replace('yourparamplaceholder', 'params:\n\tpcn: 0.1\n\tother:20\n')
    with open(filename, "w") as ff:
      ff.write(txt)

I agree with you that being able to set parameters centrally would be a good idea.

Lucas A. Meyer
  • 428
  • 3
  • 8