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

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.

Related

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 :)

How to have R markdown templates share the same set of supporting files?

I have an R package that has 4 markdown templates that can be used to knit HTML documents after installation.
These templates share the same set of supporting files (css, images, scripts, html files, ... - about 6 MB of files).
RStudio's R Markdown Document Templates page: sates that:
If want to include supporting files with your template they should be
placed in the skeleton directory. These files will be automatically
copied alongside new documents.
However, I would like to know if there is there a way for multiple templates to share one copy of these supporting files when creating a new document from a template?
The goal is to reduce the total download size of the package (package vignettes also use the same supporting files, so there are 5 * 6 MB copies all up), and to improve reproducibility (i.e. not having to update multiple copies of the assets when I make a change).
I think the answer might be further down the help page you mentioned, under "Custom Formats". Given that this is happening in a package, you should be able to create a folder, say inst/my_resources/ and place the various required files in there, perhaps in their own subfolders e.g. inst/my_resources/css, inst/my_resources/images etc. Then you can write some functions that call those resources. For the CSS, for example, follow the example of the "Quarterly Report" function in the RMarkdown help more or less directly:
First define a function to use custom CSS and header files:
use_my_css <- function(toc = TRUE) {
# get the locations of resource files located within the package
# remember that package installation moves everything in inst/ up a level
# in the directory hierarchy
css <- system.file("my_resources/css/my_styles.css", package = "mypackage")
header <- system.file("my_resources/html/header.html", package = "mypackage")
# call the base html_document function
rmarkdown::html_document(toc = toc,
fig_width = 6.5,
fig_height = 4,
theme = NULL,
css = css,
includes = includes(before_body = header))
}
Then use that function in place of the default in your template header:
---
title: "My Specific Format"
output: mypackage::use_my_css
---
The same principle should apply to the other shared resources, such as images, scripts, and so on. Within the Rmd template files you ought to be able to have code chunks that run functions leveraging system.file("<relative path>", package = "mypackage") to insert the relevant shared resources.

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?

Put figure directly into Knitr document (without saving file of it in folder) Part 2

I am extending a question I recently posted here (Put figure directly into Knitr document (without saving file of it in folder)).
I am writing an R package that generates a .pdf file for users that outputs summarizations of data. I have a .Rnw script in the package (here, my MWE of it is called test.Rnw). The user can do:
1) knit("test.Rnw") to create a test.tex file
2) "pdflatex test.tex" to create the test.pdf summary output file.
The .Rnw file generates many images. Originally, these all got saved in the current directory. These images being saved to the directory (or maybe the .aux or .log files that get created upon calling pdflatex on the .tex file) just does not seem as tidy as it could be (since users must remember to delete these image files). Secondarily, I also worry that this untidiness may cause issues when scripts are run multiple time.
So, in my previous post, we improved the .Rnw file by saving the images to a temporary folder. I have been told the files in the temporary folder get deleted each time a new R session is opened. However, I still worry about certain things:
1) I feel I may need to insert a line, like the one on line 19:
system(sprintf("%s", paste0("rm -r ", temppath, "/*")))
to automatically delete the files in the temporary folder each time the .Rnw file is run (so that the images do not only get deleted each time R gets restarted). This will keep the current directory clean of the images, and the user will not have to remember to manually delete the images. However, I do not know if this "solution" will pass CRAN standards to have a line to delete files in the temporary folder. The reason is that it deletes files in the user's system, which could cause problems if other programs are writing files to the temporary folder. I feel I have read about CRAN not allowing files to be written/deleted from the user's computer for obvious reasons. How strict would CRAN be about such a practice? Is there a safe way to go about it?
2) If writing and deleting the image files in a temporary file will not work, what is another way to accomplish the same effect (run the script without having cumbersome image files created in the folder)? Is it possible to instead have the images directly embedded in the output file (not needing to be saved to any directory)? I am pretty sure this is not possible. However, I have been told it is possible to do so with .Rmd, and that I could convert my .Rnw to .Rmd. This may be difficult because the .Rnw file must follow certain formats (text and margins) for the correct output, and it is very long. Is it possible to make use of the .Rmd capability (of inserting images directly into the output) only for the chunks that generate images, without rewriting the entire .Rnw file?
Below is my MWE:
\documentclass[nohyper]{tufte-handout}
\usepackage{tabularx}
\usepackage{longtable}
\setcaptionfont{% changes caption font characteristics
\normalfont\footnotesize
\color{black}% <-- set color here
}
\begin{document}
<<setup, echo=FALSE>>=
library(knitr)
library(xtable)
library(ggplot2)
# Specify directory for figure output in a temporary directory
temppath <- tempdir()
# Erase all files in this temp directory first?
#system(sprintf("%s", paste0("rm -r ", temppath, "/*")))
opts_chunk$set(fig.path = temppath)
#
<<diamondData, echo=FALSE, fig.env = "marginfigure", out.width="0.95\\linewidth", fig.cap = "The diamond dataset has varibles depth and price.",fig.lp="mar:">>=
print(qplot(depth,price,data=diamonds))
#
<<echo=FALSE,results='asis'>>=
myDF <- data.frame(a = rnorm(1:10), b = letters[1:10])
print(xtable(myDF, caption= 'This data frame shows ten random variables from the distribution and a corresponding letter', label='tab:dataFrame'), floating = FALSE, tabular.environment = "longtable", include.rownames=FALSE)
#
Figure \ref{mar:diamondData} shows the diamonds data set, with the
variables price and depth.Table \ref{tab:dataFrame} shows letters a through j
corresponding to a random variable from a normal distribution.
\end{document}

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.

Resources