knitr::knit_global() in RMarkdown from tempdir() in shiny

Hi, I've rendered a RMarkdown report with a template using something like this: Generating markdown report in shiny? - #12 by phil

The render includes:

render(tempReport, output_file = file,
           params = params,
           envir = new.env(parent = globalenv())

But the path where the template and word docx are is tempdir().

I want to source functions from my directory using something like knitr_knit_global(): 16.1 Source external R scripts | R Markdown Cookbook (bookdown.org)

This doesn't work though and the document doesn't render

 source("data/app_datasets.R", local = knitr::knit_global())

When I print list.files() in the markdown document, I am in the temp dir and can't seem to source the functions that I require. Any ideas?

tempdir()
#> [1] "/var/folders/0j/3g7q2zss7fb55q5wqg9t141r0000gn/T//RtmpNq1ZZL"

source("tempdir/showit.R")
#> Warning in file(filename, "r", encoding = encoding): cannot open file
#> 'tempdir/showit.R': No such file or directory
#> Error in file(filename, "r", encoding = encoding): cannot open the connection

dir(tempdir())
#> character(0)

Created on 2023-01-10 with reprex v2.0.2

Unless created with tempfile, it won't be where tempdir() looks.

Thanks @technocrat. How would you solve this? Should I define where tempdir() is? Should it be somewhere app.R document?

Or use tempfile() instead of tempdir()?

I can see how it could work in this example Trouble rendering word document with style from shiny server · Issue #1451 · rstudio/rmarkdown (github.com), but even there a knitr::knit_global() doesn't work and a list.files() in the rmd file is still in a temp file an I can't work out how to get back to the project folder from there.

I haven't tried this, but you should be able to do tempfile() which will return a file handle

tempfile()
[1] "/var/folders/0j/3g7q2zss7fb55q5wqg9t141r0000gn/T//Rtmp0vv1wg/file6c01f2e1086"

where Rtmp0vv1wgj should persist across sessions. I'd need to take a deep look at help(tempfile) and play around a bit to feel confident because I'm not sure whether the approach is affected by the call to render taking place in a child environment.

1 Like

Thanks. I'll give it a go later.

I'm going to go with a different solution, which is to pass the objects (heaps of graphs) as a param, instead of passing the dataframe and creating the graphs in the Rmd document.

1 Like