knitr with Shiny: temporary directory - r

I've built a Shiny app that estimates a model; I would like the user to be able to download a summary of the model in a pdf format when the estimation is finished. I've included a download button in the app as follows:
output$download_estimation = downloadHandler(
filename = "report.pdf",
content = function(file) {
withProgress(message = 'Generating...', {
rmarkdown::render('report_model.Rmd', output_file = file)
})
})
The file 'report_model.Rmd' uses a custom LaTeX template. The issue is that, whenever I click the download button in Shiny, knitr evaluates the chunks but after that I get a LaTeX error of 'Undefined control sequence.' This occurs because the paths to figures in the report within \includegraphics{} are incorrectly specified: instead of using only forwards slashes in the file path, knitr produces a combination of backward and forward slashes, for example
\includegraphics{C:\Users\admin\AppData\Local\Temp\Rmksdfj0568\report_model_files/figure-latex/unnamed-chunk-5-1.pdf}.
When I knit the exact same document from RStudio outside of Shiny, this does not happen because the .tex is not produced in the temporary directory but rather in the directory where the .Rmd is placed and I get the correct path as
\includegraphics{report_model_files/figure-latex/unnamed-chunk-5-1.pdf}.
Moreover, when I don't use the custom template but rather the Pandoc built-in one, everything works fine. I was, however, unable to figure out why the use of custom template makes the difference. Is there a way to fix this?

The solution to this issue, at least in this specific case, is to include
```{r, echo = FALSE, include = FALSE}
knitr::opts_knit$set(base.dir = normalizePath(tempdir(), winslash = '/'))
knitr::opts_chunk$set(fig.path = "figure/")
```
in the beginning of the 'Rmd' file that uses the custom template. This works when the app is run locally, the solution may not work when the app is deployed.

Related

Is it possible to knit an R Markdown file only to a preview window/pane in RStudio without saving an html file?

I would like to keep the base folder of my R Markdown project tree as uncluttered as possible and still use the Knit button in RStudio to see some results as an HTML output in the RStudio's preview window. However, every time I knit, an HTML file is created to the base folder along my .Rmd files.
My folder structure might look like this:
If I've understood correctly - and do please correct me if I'm wrong - it is not very straightforward to output the HTML files to an upstream folder (here:"results" folder) from an R Markdown file by pressing the Knit button, so I would be willing to:
prevent the creation of HTML files altogether,
still see the results in an HTML format in RStudio's preview window, and
only when I'm really willing to save an HTML file, save (export) such a file and (manually) transfer it to the results folder.
So, if there is no easy way of directing the HTML files to the "results" folder, can I prevent the creation of HTML files altogether and only preview the results in the preview window?
I don't know of a way to attach this to the knit button, but you could write a function that does this:
get the current file open in the edit pane. This answer gives details on that.
run rmarkdown::render() with the output_dir argument set the way you want.
You can attach this function to a keyboard shortcut in RStudio using these instructions.
Here's a simple version of the function:
knit2 <- function(filename = rstudioapi::getSourceEditorContext()$path,
output_dir = tempdir()) {
result <- rmarkdown::render(filename, output_dir = output_dir)
getOption("viewer")(result)
}
Simply call knit2(), and the output will be written to tempdir(), which means the preview will appear in the Viewer pane. If you want it to write to "results", call it as
knit2(output_dir = "results")
If that's not a subdirectory of tempdir(), the preview will appear in an external browser.

choose working directory in code option of r chunk

So I am using RMarkdown and I am sourcing code from a script contained in a separate folder (Scripts) at the same level as the folder which contains the Markdown file (Report). Both directories are at the root of the R project.
I achieve that first by setting the working directly using the following code in the setup chunk:
knitr::opts_knit$set(root.dir = normalizePath(".."))
Then calling the following in a R chunk:
```{r datacreation, echo = FALSE}
source("./Scripts/20212022Summary.R")
```
All that is great but I also want to display later on in the knitted document, the whole code contained in that script so it can be reviewed if necessary.
To achieve this, I do :
```{r 20212022Summary_readlinesversion, code = readLines("../Scripts/20212022Summary.R"),echo=TRUE,include = knitr::is_html_output(),cache=FALSE,eval = FALSE}```
Which just shows the code without running it, with a nice formatting.
What I would like to know is how I would go about defining once and for all what is my working directory for consistency sake. Specifically when I call code = readLines("../Scripts/20212022Summary.R") I clearly operate with the knowledge it will consider the working directory to be the one containing the report instead of the one (parent directly aka project root directory) which I defined previously in the set up chunk.
Ideally I would define things once and for all, especially as then I could pick those up programmatically and source from anywhere within the project folder, consistently.
Anyone has tips on how to achieve this? What I have done works, it's just ugly, manual and not consistent. And it bugs me :)

R package to knit a markdown document given some data

I am writing a basic R package that reads in data from a user specified database and spits out a markdown report with predefined graphs and tables etc. I have placed the .Rmd file in the R folder, and have a user level function that reads in the data and knits it.
# create_doc.R
create_doc <- function(directory = NULL,
database_name_name) {
if (is.null(directory)) directory <- tclvalue(tkchooseDirectory(
title = "Choose Folder for Input and Output"))
rmarkdown::render("R/doc_generator.Rmd", output_dir = directory)
}
This works fine on my computer, but when I build the package, the .Rmd file has been deleted. This means I can't give it to other users for use on other computers. I realise that the R folder may not be the correct place for this file (I guess it deletes any files not ending in .R), but I'm not sure where else to put it. It is not package documentation, it creates the end result when using the package.
Googling has not helped so far. Is it possible to knit a document using a function in an R package? If yes, what am I doing wrong. If no, are there any other suggestions on how to achieve this?

R: In RStudio how do I make knitr output to a different folder to avoid cluttering up my drive?

I am using RStudio's knit HTMl function to output some presentations. But it always outputs the files to my current work directory. How can I make it output to another directory so that my directory is clean with only the original .rmd files?
The trick mentioned in Rmarkdown directing output file into a directory worked for me.
Example: Add the following to the YAML preamble as a top-level item to write output to the pdf/ subdirectory:
knit: (function(inputFile, encoding) {
rmarkdown::render(inputFile, encoding = encoding, output_dir = "pdf") })
As Eric pointed out in the comments, if you're willing to forego the convenience of the Knit HTML button (which produces HTML files that live alongside your .Rmd), you can just call rmarkdown::render directly.
However, if you really need to customize your workflow, you can override the Knit HTML button to run whatever command you via the rstudio.markdownToHTML option. This command could invoke rmarkdown with specific options (such as output directory) and perform other pre- or post-processing tasks. Documentation here:
https://support.rstudio.com/hc/en-us/articles/200552186-Customizing-Markdown-Rendering
Note that setting the rstudio.markdownToHTML option will turn off some of the newer RMarkdown V2 integration features baked into RStudio, since RStudio will no longer be able to infer what engine is being used to render the document.
Here's how I go about solving this problem.
Lets say we have two Markdown files titled 'my_report_eng.rmd' and 'my_report_fr.rmd'
as well as an output directory in /c/docs/reports/output/ as well as a location of these rmds in a source directory we will call /c/docs/reports/source.
Goal is to run these two rmd files and output the results to our Output path. We can write a simple R script to achieve this.
source_folder <- file.path("C:","docs","reports","source")
output_folder <- file.path("C:","docs","reports","output")
timestamp <- Sys.Date()
#render english report
rmarkdown::render(input = paste0(source_folder, "/", "my_report_eng.rmd"),
output_format = "word_document",
output_file = paste0("report_en_", timestamp, ".docx"
output_dir = output_folder)
#render french report
rmarkdown::render(input = paste0(source_folder, "/", "my_report_fr.rmd"),
output_format = "word_document",
output_file = paste0("report_fr_", timestamp, ".docx"
output_dir = output_folder)
This method can be extended beyond two reports, or obviously scaled down to one.

How to display images in Markdown on github generated from knitr without using external image hosting?

I like uploading repositories to github that include multiple R Markdown and Markdown files.
Here is an example of such a markdown file on github. And here's a screen grab.
The problem is that images do not display. You can click on the image, and you will go to where the file is stored.
The file referenced is:
https://github.com/... /blob/.../myfigure.png
whereas I presume it needs to reference
https://github.com/... /raw/.../myfigure.png
Things I considered:
imgur: I could use external image hosting (e.g., see this example) by adding the following code:
```{r setup}
opts_knit$set(upload.fun = imgur_upload) # upload all images to imgur.com
````
However, for various reasons I don't want to do this (I have trouble uploading when behind a firewall; it's slow; it creates an unnecessary dependency)
Rpubs: There's also RPubs which is quite cool. However, at time of posting it seems more suited to single markdown documents rather than multiple R markdown documents. And it doesn't provide such a close link between source R Markdown and the Markdown document.
Question
Is there a workflow for using R Markdown and knitr to produce Markdown files which when uploaded to github permit the Markdown file to display images stored in the github repository?
This used to be part of the minimal example, use
opts_knit$set(base.url='https://github.com/.../raw/.../')
See the changes here and here.
Also see http://yihui.name/knitr/options.
EDIT [with update to restore base.url to former value
Regarding switching, you could define a function as
create_gitpath <- function(user, repo, branch = 'master'){
paste0(paste('https://github.com', user, repo, 'raw', branch, sep = '/'),'/')
}
my_repo <- create_gitpath(user, repo)
knit.github <- function(..., git_url ){
old_url <- opts_knit$get('base.url')
on.exit(opts_knit$set(base.url = old_url))
opts_knit$set(base.url = git_url)
knit(..., envir = parent.frame())
}
Run with knit until you want to push to github then run knit.github(..., git_url = my_repo)
What about the following code at the beginning of your markdown file?
``` {r setup,echo=FALSE,message=FALSE}
gitsubdir <- paste(tail(strsplit(getwd(),"/")[[1]],1),"/",sep="")
gitrep <- "https://github.com/mpiktas/myliuduomenis.lt"
gitbranch <- "master"
opts_knit$set(base.url=paste(gitrep,"raw",gitbranch,gitsubdir,sep="/"))
```
It is possible to tweak it so that gitrep and gitbranch will be reported by git. Here I assumed that I am one directory level below the main git repository directory. Again this might be tweaked to accommodate more complicated scenarios.
I've tested on github, here is the Rmd file and corresponding md file.

Resources