Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Update render_report.R to support quarto files #118

Merged
merged 2 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ RUN R -e "install.packages(c( \
'RCurl', \
'REDCapR', \
'RMariaDB', \
'argparse', \
'checkmate', \
'dbx', \
'digest', \
Expand Down
53 changes: 32 additions & 21 deletions report/render_report.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,49 @@ library(lubridate)
library(rmarkdown)
library(sendmailR)
library(redcapcustodian)
library(argparse)

init_etl("render_report")

if (!dir.exists("output")){
dir.create("output")
}

parser <- ArgumentParser()
parser$add_argument("script_name", nargs=1, help="Script to be run")
if (!interactive()) {
args <- commandArgs(trailingOnly = T)
script_name <- word(args, 2, sep = "=")
args <- parser$parse_args()
script_name <- args$script_name
if(!fs::file_exists(script_name)) {
stop(sprintf("Specified file, %s, does not exist", script_name))
}
} else {
script_name <- "sample_report.Rmd"
script_name <- "dummy.qmd"
stop(sprintf("Specified file, %s, does not exist", script_name))
}

report_name <- word(script_name, 1, sep = "\\.")
report_type <- word(script_name, 2, sep = "\\.")

script_run_time <- set_script_run_time()
output_file <-
paste0(str_replace(report_name, ".*/", ""),
"_",
format(script_run_time, "%Y%m%d%H%M%S"),
if_else(report_type == "qmd", ".pdf", "")
)

if (report_type == "qmd") {
quarto::quarto_render(
script_name,
output_file = output_file,
output_format = "pdf"
)
} else {
render(
script_name,
output_file = output_file
)
}

output_file <- here::here(
"output",
paste0(report_name,
"_",
format(script_run_time, "%Y%m%d%H%M%S"))
)

full_path_to_output_file <- render(
here::here("report", script_name),
output_file = output_file
)

output_file_extension <- word(full_path_to_output_file, 2 , sep = "\\.")
attachment_object <- mime_part(full_path_to_output_file, basename(full_path_to_output_file))
output_file_extension <- word(output_file, 2 , sep = "\\.")
attachment_object <- mime_part(output_file, output_file)

email_subject <- paste(report_name, "|", script_run_time)
body <- "Please see the attached report."
Expand Down
2 changes: 2 additions & 0 deletions study_template/cron/quarto_html_example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Run the example Quarto report
17 8-17 * * * root /usr/bin/docker run --rm --env-file /rcc/study_template/.env rcc.site Rscript report/render_report.R report/quarto_html_example.qmd
2 changes: 1 addition & 1 deletion study_template/cron/sample_report
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Run the sample Rmd report
05 8-17 * * * root /usr/bin/docker run --rm --env-file /rcc/study_template/.env rcc.site Rscript report/render_report.R script_name=sample_report.Rmd
05 8-17 * * * root /usr/bin/docker run --rm --env-file /rcc/study_template/.env rcc.site Rscript report/render_report.R report/sample_report.Rmd
27 changes: 27 additions & 0 deletions study_template/report/quarto_html_example.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: "Quarto HTML example"
author: "John Doe"
format: html
editor: visual
---

## Quarto

Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see <https://quarto.org>.

## Running Code

When you click the **Render** button a document will be generated that includes both content and the output of embedded code. You can embed code like this:

```{r}
1 + 1
```

You can add options to executable code like this

```{r}
#| echo: false
2 * 2
```

The `echo: false` option disables the printing of code (only output is displayed).
26 changes: 26 additions & 0 deletions study_template/report/quarto_pdf_example.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: "Quarto PDF example"
format: pdf
editor: visual
---

## Quarto

Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see <https://quarto.org>.

## Running Code

When you click the **Render** button a document will be generated that includes both content and the output of embedded code. You can embed code like this:

```{r}
1 + 1
```

You can add options to executable code like this

```{r}
#| echo: false
2 * 2
```

The `echo: false` option disables the printing of code (only output is displayed).
46 changes: 32 additions & 14 deletions study_template/report/render_report.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,49 @@ library(lubridate)
library(rmarkdown)
library(sendmailR)
library(redcapcustodian)
library(argparse)

init_etl("render_report")

parser <- ArgumentParser()
parser$add_argument("script_name", nargs=1, help="Script to be run")
if (!interactive()) {
args <- commandArgs(trailingOnly = T)
script_name <- word(args, 2, sep = "=")
args <- parser$parse_args()
script_name <- args$script_name
if(!fs::file_exists(script_name)) {
stop(sprintf("Specified file, %s, does not exist", script_name))
}
} else {
script_name <- "sample_report.Rmd"
script_name <- "dummy.qmd"
stop(sprintf("Specified file, %s, does not exist", script_name))
}

report_name <- word(script_name, 1, sep = "\\.")
report_type <- word(script_name, 2, sep = "\\.")

script_run_time <- set_script_run_time()
output_file <-
paste0(str_replace(report_name, ".*/", ""),
"_",
format(script_run_time, "%Y%m%d%H%M%S"),
if_else(report_type == "qmd", ".pdf", "")
)

if (report_type == "qmd") {
quarto::quarto_render(
script_name,
output_file = output_file,
output_format = "pdf"
)
} else {
render(
script_name,
output_file = output_file
)
}

output_file = paste0(report_name,
"_",
format(script_run_time, "%Y%m%d%H%M%S"))

full_path_to_output_file <- render(
paste0("report/", script_name),
output_file = output_file
)

output_file_extension <- word(full_path_to_output_file, 2 , sep = "\\.")
attachment_object <- mime_part(full_path_to_output_file, paste0(output_file, ".", output_file_extension))
output_file_extension <- word(output_file, 2 , sep = "\\.")
attachment_object <- mime_part(output_file, output_file)

email_subject <- paste(report_name, "|", script_run_time)
body <- "Please see the attached report."
Expand Down
2 changes: 1 addition & 1 deletion vignettes/custom_rscript.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ Stop and think about architecture and study lifecycle.
If you need something to run periodically, you need to make it easy to run with all of its dependencies packaged up and you need to schedule it. The modern way to package dependencies is to put them all into a container, add your application and run the container. REDCap Custodian supports containerization with Docker. The [`./study_template/Dockerfile`](https://github.com/ctsit/redcapcustodian/tree/master/study_template/Dockerfile) is template you can use to containerize your RScript and RMarkdown. Adapt it to your needs and build the container with [./build.sh](https://github.com/ctsit/redcapcustodian/tree/master/build.sh). If you have good container infrastructure, use it to build and deploy your containers.

Running automated R Markdown reports from docker requires the use of an Rmd renderer.
[render_report.R](https://github.com/ctsit/redcapcustodian/tree/master/study_template/report/render_report.R) contains functionality to knit an Rmd, email it and then log the job run. The Rmd script name is passed as a command line argument to [render_report.R](https://github.com/ctsit/redcapcustodian/tree/master/study_template/report/render_report.R) via cron. Refer to [sample_report](https://github.com/ctsit/redcapcustodian/tree/master/study_template/cron/sample_report) for an example cron job.
[render_report.R](https://github.com/ctsit/redcapcustodian/tree/master/study_template/report/render_report.R) contains functionality to knit an Rmd or a Qmd, email it and then log the job run. The Rmd/Qmd script name is passed as a command line argument to [render_report.R](https://github.com/ctsit/redcapcustodian/tree/master/study_template/report/render_report.R) via cron. Refer to [sample_report](https://github.com/ctsit/redcapcustodian/tree/master/study_template/cron/sample_report) for an example cron job.

## Automation with Linux and cron

Expand Down