Search code examples
rr-markdownflexdashboard

How can I generate and knit personalized versions of an .Rmd report?


I have created a report PerfReport.Rmd that compares one person's performance to the performance of a large group. I have hundreds of individuals that should receive a personalized version of this report, comparing their own performance to the large group.

Obstacles I see are: 1. I need each filename to include the person's name. 2. Each file has calculations that are specific to the person.

Here's an example .Rmd

---
title: "Course Success"

output:
html_document: flexdashboard::flex_dashboard
pdf_document: default

---
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(dplyr)
library(plotly)
```

```{r comp, echo=FALSE, message=FALSE,warning=FALSE}

df<-data.frame(Person=c('a','a','a','a','a','b','b','b','b','b','c','c','c','c','c','d','d','d','d','d'),
           Success=c(1,0,1,1,0,1,0,0,0,0,1,1,1,1,1,0,1,0,0,1),
           Valid=c(1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1))

testperson<-'b'

comparison<-df%>%
  transmute(Your_Rate=sum(Success[Person==testperson])/sum(Valid[Person==testperson]),
        Baseline=sum(Success[Person!=testperson])/sum(Valid[Person!=testperson]))%>%
  distinct(Your_Rate,.keep_all = TRUE)

plot_ly(comparison,y=~Your_Rate, type='bar')%>%
  add_trace(y=~Baseline)

```

As I have it structured, a variable in the .Rmd defines the person that the calculations are being made for, and the only way I'm taking care of filenames is by manually saving a file with the person's name before knitting.

My guess at how to accomplish this is to:

  1. Produce .Rmd files with the names of each person appended,(i.e PerfReport_a.Rmd, PerfReport_b.Rmd) and change the testperson variable in each file.
  2. Run a script that knits each of these .Rmd files into a set of html files.

If I'm right about the general steps here, I have step 2 covered with a .R file that knits every .Rmd file within a directory.

files<-list.files("E:/Dashboards/",pattern = "[.]Rmd$")

files2<-as.data.frame(files)
files3<-files2%>%
  mutate(filenow=paste0("E:/Dashboards/",files))

files4<-files3$filenow

for (f in files4) rmarkdown::render(f)

Any help with a means of generating the .Rmd files with the adjusted values for testperson would be greatly appreciated. If there is simply a better means of getting from a single, master .Rmd to the hundreds of personalized .html dashboards I'm looking to produce, I would love to learn that method, too!

Thank you in advance.


Solution

  • You can use yaml parameter params to get this right. You will need

    • one template (template.Rmd)
    • script to run the template (script.R)

    Here is a small trivial example:

    template.Rmd

    ---
    title: no title
    author: Roman
    date: "`r Sys.Date()`"
    params:
      testperson: NA
    ---
    
    ```{r}
    print(params$testperson)
    ```
    
    ```{r}
    sessionInfo()
    ```
    

    script.R

    library(rmarkdown)
    
    persons <- c("person1", "person2", "person3")
    
    for (person in persons) {
      rmarkdown::render(input = "template.Rmd",
                        output_file = sprintf("%s_report.html", person),
                        params = list(testperson = person)
                        )
    }
    

    This should populate your working folder with personX_report.html files (see screenshot below).

    enter image description here