I'm trying to make a "downloadable html report" from my shiny app, however when I deploy the app to shinyapps.io and try to download the report, it fails because I can't render the image in the R markdown file. It works fine locally, which means I think the issue is to do with the relative file path.
Short example made for ease:
app.R
library(shiny)
library(dplyr)
library(tidyverse)
library(knitr)
library(here)
#load pca plots from working directory
pca <- list.files(pattern="*pca_check.png")
#move file to www folder for it to render correctly
dir.create("www")
file.copy(pca[[1]], "www")
#pca[[1]] is "sept_2021.pca_check.png"
##################
# Make Shiny App #
##################
ui <- fluidPage(titlePanel("QC output"),
navbarPage("Menu",
tabPanel("Report",
sidebarLayout(
sidebarPanel(downloadButton("report", "Generate report"), width=0
),
mainPanel(tags$h2("Ancestry prediction Peddy"),
a(img(src=pca[[1]], height = 500, width = 300, slign="center",
target="_blank"),
href=pca[[1]])
)))))
server <- function(input, output) {
output$report <- downloadHandler(
# For PDF output, change this to "report.pdf"
filename = "report.html",
content = function(file) {
tempReport <- file.path(tempdir(), "report.Rmd")
file.copy("report.Rmd", tempReport, overwrite = TRUE)
# Set up parameters to pass to Rmd document
params <- list(pca = pca[[1]])
rmarkdown::render(tempReport, output_file = file,
params = params,
envir = new.env(parent = globalenv())
)
}
)
}
shinyApp(ui = ui, server = server)
NB: the image displays fine in the app when using this code:
a(img(src=pca[[1]], height = 500, width = 300, slign="center",
target="_blank"),
href=pca[[1]])
However, when generating the report, it fails...
report.Rmd
---
title: "Dynamic report"
output: html_document
params:
pca: NULL
---
PCA plot
```{r out.width="70%"}
knitr::include_graphics(here::here(pca))```
If it don't use here::here(pca)
the code fails locally. However it's clearly giving the wrong path when deployed. So, instead I tried just:
knitr::include_graphics(pca)
That still fails when deployed. The full app is here: https://lecb.shinyapps.io/QC_sept_21/ and the image in question was successfully uploaded to https://lecb.shinyapps.io/QC_sept_21/sept_2021.pca_check.png, which implies I am referring to the correct directory... perhaps the markdown doesn't know what the "working directory" is?
Anyone have any idea how to get the image to render in the downloadable report please?
Many thanks!
knitr::rendr
treats the folder where the .Rmd
file sits as root. You are copying your report.Rmd
to a temp folder. Thus, copying your png
to the same temp folder and referencing it without here
should do the trick remotely and locally:
Untested code snippet:
output$report <- downloadHandler(
# For PDF output, change this to "report.pdf"
filename = "report.html",
content = function(file) {
tmp_dir <- tempdir()
tempReport <- file.path(tmp_dir, "report.Rmd")
tmp_pic <- file.path(tmp_dir, pca[[1]])
file.copy("report.Rmd", tempReport, overwrite = TRUE)
file.copy(pca[[1]], tmp_pic, overwrite = TRUE)
# Set up parameters to pass to Rmd document
params <- list(pca = pca[[1]])
rmarkdown::render(tempReport, output_file = file,
params = params,
envir = new.env(parent = globalenv())
)
}
)
and
---
title: "Dynamic report"
output: html_document
params:
pca: NULL
---
PCA plot
```{r out.width="70%"}
knitr::include_graphics(params$pca)
```