-1

Consider as an input the tibble:

in_data <- tribble(
~ style, ~input1, ~input2, ~text_input
'style_1', 5, NA, 'first result',
'style_2', 4, 6, 'fun',
'style_1', 2, NA, 'other result')

I would like to do the following:

  • have different patterns, e.g. style_1 and style_2 of the kind

style_1.Rmd

---
params:
 input1: NA
 text_input: ''
---
`r params$text_input` is of the value `r params$input1`

style_2.Rmd

---
params:
 input1: NA
 input2: NA
 text_input: ''
---
```{r}
plot(params$input1, params$input2, main=params$text_input)
```
  • somehow in_data %>% pmap(parse_and_knit) the documents, where every row gets knitted with its corresponding style and arguments, and finally composed into a document, which would need an additional header probably.

There is heddlr https://github.com/mikemahoney218/heddlr which does something similar. But it seems to rely on replacing a single argument per "pattern" (which is my "style"). I could make that argument a row number and go pull out data with this information; it would be nicer to take the entire row as params input in pmap style.

Is that possible? I can just knit every piece individually, but I need to compose it to a report in the end, preferably without doing my own DOM magic.

meow
  • 925
  • 7
  • 22

1 Answers1

1

Thanks to @Jon Spring, the following is very close to what I want.

  • The R script passes the data frame as a params item for rmarkdown::render
  • The logic looping through the rows is in the report template (not, as I initially intended, in the R script that triggers report generation).
  • The row data is put into an environment and passed in with envir. I could also assign the column variables directly into envir, so they could be accessed directly without data$, but I'm not yet sure if I want that.
  • Note: probably pwalk(..., ~cat(...)) is better than cat(pmap_chr(...) %>% str_flatten()).

In the script generate_report.R:

library(knitr)
library(tidyverse)
in_data <- tribble(
  ~ style, ~input1, ~input2, ~text_input,
  'style1', 5, NA, 'first result',
  'style2', 4, 6, 'fun',
  'style1', 2, NA, 'other result')


rmarkdown::render("rmdreport.Rmd", params = list(data = in_data))

In the report template report.Rmd

---
title: "report title"
output: html_document
params:
  data: NA
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, results='asis')
```

# Report

This is the intro to the report. What follows is one block per row in `params$data`.

```{r}

in_data <- params$data

cat(
  pmap_chr(in_data, function(...) {
  data <- list(...)
  envir = new.env()
  envir$data <- data
  knitr::knit_child(glue("{data$style}.rmd"), envir = envir, quiet = TRUE)
}) %>% str_flatten())

```

The individual templates/styles:

style1.Rmd

## Section on the topic `r data$text_input`

`r data$text_input` is of the value `r data$input1`

style2.Rmd

## Section with a plot

```{r}
plot(data$input1, data$input2, main=data$text_input)
res <- data$input1 * data$input2
cat(glue("{data$input1} * {data$input2} = {res}"))
```
meow
  • 925
  • 7
  • 22
  • Similar solution here: https://somtom.github.io/post/using-dynamically-rendered-r-markdown-childs-for-reports/ related to https://stackoverflow.com/questions/21729415/generate-dynamic-r-markdown-blocks/21730473#comment65652301_21730473 – meow Mar 18 '21 at 09:40
  • This is great, yes Rmarkdown reporting with params and child docs allows for such diverse reporting. Remember these all have to be in the same directory when rendering too – Daniel_j_iii Mar 26 '21 at 00:39