I am trying to create automated fitness testing reports by training hub using RMarkdown. I am building off a previous question I asked on the topic here using the same dataframe structure and similar code.
I would like to slightly customize each RMarkdown report based on hub while still allowing it to be an automated process (i.e. 1 script + 1 .rmd). For example, all hubs will have the Broad Jump plot but for A I want a broad jump plot and a 10m sprint plot.
I have tried using params in the YAML and render function but not had any luck so far.
Sample Data
Date Athlete Test Average Hub
1 2019-06-03 Athlete1 Broad_Jump 175.000000 A
2 2019-06-10 Athlete1 Broad_Jump 187.000000 A
3 2019-06-10 Athlete2 Broad_Jump 200.666667 B
4 2019-06-10 Athlete3 10m_Sprint 1.831333 B
5 2019-06-10 Athlete2 10m_Sprint 2.026667 B
6 2019-06-17 Athlete1 Broad_Jump 191.500000 A
7 2019-06-17 Athlete2 Broad_Jump 200.666667 B
8 2019-06-17 Athlete3 10m_Sprint 1.803667 B
9 2019-06-17 Athlete2 10m_Sprint 2.090000 B
10 2019-06-24 Athlete1 Broad_Jump 192.000000 A
R Script
library(rmarkdown)
library(knitr)
library(dplyr)
library(ggplot2)
WT <- read.csv("WT.csv")
WT_10m <- WT %>%
filter(Test == "10m_Sprint") %>%
select(Date, Athlete, Hub, Average)
plot2 <- ggplot(WT_10m, aes(x=Date, y=Average))+
geom_point()
for (hub in unique(WT$Hub)){
subgroup <- subset(WT, Hub == hub)
render(
input = "Hub_Test.rmd",
params = list("plot2"=plot2),
output_file = paste0('report.', hub, '.pdf'))
.Rmd File
---
title: "WT Monitoring: Hub"
output: pdf_document
params:
plot2: plot2
hub:
label: "hub"
value: A
choices: [A, B]
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(rmarkdown)
library(knitr)
library(dplyr)
library(ggplot2)
WT <- read.csv("WT.csv")
subgroup <- subset(WT, Hub == hub)
subgroup_Broad <- subgroup %>%
filter(Test == "Broad_Jump") %>%
select(Date, Athlete, Hub, Average)
ggplot(subgroup_Broad, aes(x=Date, y= Average)) +
geom_point()
params$plot2
I'm not sure whether to use params, the render file, or some other method to accomplish this task. There are several hubs and tests so I'm trying to avoid having a separate Rmarkdown template for each hub.
So I have no idea whether this is the most efficient solution (probably not). Also it was not completely clear for me what code you want to run exactly, so below you find someting general which you have to adjust a bit to your specific situation.
If I understand correctly you want to run the markdown at least twice with slightly different settings. What I would do is indeed using params and create a function, which specifies the render. I think you had it almost right, but I am unsure about you label, value and choices part. So that is the thing I would change.
So in the markdown you need the specify the params with a default setting (I also include title as I think each report should have its own title). I here assumed you want a html doc, but you can adjust that ofcourse
author: "Author"
date: "Dec 24, 2019"
params:
hub: "B"
title: "Some basic title"
output: html_document
The first thing you should put after specifing the author, date, parmas and output is:
---
title: `r params$title`
---
The dashes need to be included. This wil give your document the specific title you want. After this you can do whatever you want with the code till you reach the point where you want to include plot2 (the sprint plot).There I would do something like:
if(params$hub == "A"){
YOUR PLOT CODE FOR PLOT 2
}
So the plot will only be run if the param of hub is A (or if you actuall want it for multiple than use %in% c("A","") ). You can put more code after this if you want.
Than in the script you can use the render function to changes the params. I put it in my own function: again you can change the name of the function if you want and be sure to check whether the .html matches your markdown document output. I use this user defined functions so I can run multiple inputs through the render and get a different output.
render_html_fun <- function(hub_in){
rmarkdown::render('FILE LOCATION WHERE YOU SAVE THE RMD FILE.Rmd',
output_file = paste0('SOME TITLE', hub_in, "_", Sys.Date(), '.html'),
params = list(hub = hub_in,
title = paste0("SOME BASIC TITLE", hub_in)))
}
So basically the title of your knitted document will be saved with the basic title + the hub so that you know beforehand which file you are opening. So next thing to do in your scipt is one by one put your hubs into the function. As a result you will get a document for each hub separately.
hubs_input <- c("B", "A")
library(purrr)
walk(hubs_input, render_html_fun)
Personally, I use the c() function and manually specify the dimensions, so that
1 you do not have to load the data twice (once in the script and once in the markdown), especially when your data is big loading the data twice is not prefered
2 you can than choose not to run the script for a specific level if you do not want to.
But ofcourse if you prefer, you can also replace the c()
part with your unique(WT$Hub)
part.
Edit: I also found the website very usefull.