R: Correctly Using the "rmarkdown::render()" Function - r

I am working with the R programming language.
My Question: I am trying to learn how to use the rmarkdown::render() function in R.
For example, suppose I have the following R Markdown Code:
---
title: "Storyboard Commentary"
output:
flexdashboard::flex_dashboard:
storyboard: true
---
### A nice scatterplot here
```{r}
plot(cars, pch = 20)
grid()
```
---
Some commentary about Frame 1.
### A beautiful histogram on this board
```{r}
hist(faithful$eruptions, col = 'gray', border = 'white', main = '')
```
---
Some commentary about Frame 2.
I copied and pasted the above code into a Notepad document - and then saved this file as "test_render.Rmd".
Now, I want to use the render() function to execute this file, e.g. rmarkdown::render("test_render.Rmd") - but I am not sure how I can import this file into R using code (i.e. without manually clicking/pointing on the file).
The reason I am asking about this, is because I am using a computer at school where we only have the older GUI version of R (i.e. we do not have R Studio) and I would like to directly import an .Rmd file into R and use this render() function, and create the final result.
Can someone please show me how to do this?
Thanks!

You should be able to render the rmarkdown file and export it using the input and output arguments of render, i.e.
rmarkdown::render(input = "test_render.Rmd", output_file = "test_render.html")
It should save in your current working directory.

Related

profvis stalling on function within markdown on linux

I would like to profile some functions in R, using profvis(), on a linux command line (outputting html)
I have tested this with the approach here, and it works. I saved the code in that link into a file named "test.Rmd". At the moment I am simply going into an R environment in linux and typing 'rmarkdown::render("test.Rmd")', and it produces a HTML file with the code chunks and the 'profvis' chart. Fine.
This is the code & function I want to profile;
title: "Untitled"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r packages}
library(data.table)
library(terra)
```
## profvis
This is an R Markdown document using profvis.
```{r settings}
# Functions used .
source("funcs.R")
```
```{r objects}
dt_a <- fread("a_table.csv")
dt_a <- fread("a_table.csv")
r_c <- rast("c_surface.tif")
```
```{r process}
myFunctoProf(year = 2020, arg_a = dt_a, arg_b = dt_b, arg_c = r_c,
req_string = "data/lookup_stuff.csv")
```
The above runs to completion in about 5 minutes, produces a HTML file, and outputs the results onto my computer (rasters). There are 3 further functions called within the myFunctoProf() function.
However, as soon as I put the profvis() function back in, as in the link above, the markdown seems to run indefinitely, it never completes and never errors and doesn't produce raster outputs or a HTML file.
```{r process}
profvis({
myFunctoProf(year = 2020, arg_a = dt_a, arg_b = dt_b, arg_c = r_c,
req_string = "data/lookup_stuff.csv")
})
```
Is the profvis() function struggling with the nested functionality? one of the functions called within myFunctoProf() is used in 'lapply', does that matter?
edit: wondered if it might be to do with the linux cluster using cores/nodes when using lapply(subFunc) within the main function call.

Getting flextable to knit to PDF

I feel like I've gone down a rabbit hole when all I want is some nice tables in my pdf. Long story, here goes:
I want to print some tables to a PDF from r markdown. I usually use Kable and it works fine. That being said, this table is going to have some really long values, and an unknown number of columns that get generated, and I was having a hard time specifying which column would be what width when I didn't know yet in kable. Anyhow, that led me to flextable.
When I knit to html, the table looks great, like so:
But I'm having trouble knitting to pdf. I understand, via other stack answers, that flextable's need to be saved as images to be plotted to pdf. So I have code like this:
ft <- flextable(x)
ft <- autofit(ft)
tf <- tempfile(fileext = ".png")
## Not run:
if( require("webshot2") ){
save_as_image(x = ft, path = "myimage.png")
}
plot(tf)
But at first it gave me the error that I didn't have the webshot2 package, so after some trouble I installed that (it didn't line up with my version of R (I'm on rstudio.cloud) and then when I try to run it now, it says
Am I missing something obvious? How do I save a flextable as an image and then plot it in my pdf?
I've also tried Joanna's solution here: Is it possible to generate the RTable (FlexTable) in pdf with RMarkdown? and r tells me could not find function "as.html". Even though both flextable and htmltools have been loaded.
P.s. providing reproducible data would be very long given all the code that generates the tables and the fact I need it to knit into a pdf, will provide rstudio.cloud link if anyone is interested
You can now produce PDF without the need of webshot package (flextable >= 0.6.0):
---
title: "Untitled"
output:
pdf_document:
latex_engine: xelatex
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(flextable)
```
```{r}
ft <- flextable(head(airquality))
ft <- autofit(ft)
theme_vader(ft)
```

Modularized R markdown structure

There are a few questions about this already, but they are either unclear or provide solutions that don't work, perhaps because they are outdated:
Proper R Markdown Code Organization
How to source R Markdown file like `source('myfile.r')`?
http://yihui.name/knitr/demo/externalization/
Modularized code structure for large projects
R Markdown/Notebook is nice, but the way it's presented, there is typically a single file that has all the text and all the code chunks. I often have projects where such a single file structure is not a good setup. Instead, I use a single .R master file that loads the other .R files in order. I'd like to replicate this structure using R Notebook i.e. such that I have a single .Rmd file that I call the code from multiple .R files from.
The nice thing about working with a project this way is that it allows for the nice normal workflow with RStudio using the .R files but also the neat output from R Notebook/Markdown without duplicating the code.
Minimal example
This is simplified to make the example as small as possible. Two .R files and one master .Rmd file.
start.R
# libs --------------------------------------------------------------------
library(pacman)
p_load(dplyr, ggplot2)
#normally load a lot of packages here
# data --------------------------------------------------------------------
d = iris
#use iris for example, but normally would load data from file
# data manipulation tasks -------------------------------------------------
#some code here to extract useful info from the data
setosa = dplyr::filter(d, Species == "setosa")
plot.R
#setosa only
ggplot(setosa, aes(Sepal.Length)) +
geom_density()
#all together
ggplot(d, aes(Sepal.Length, color = Species)) +
geom_density()
And then the notebook file:
notebook.Rmd:
---
title: "R Notebook"
output:
html_document: default
html_notebook: default
---
First we load some packages and data and do slight transformation:
```{r start}
#a command here to load the code from start.R and display it
```
```{r plot}
#a command here to load the code from plot.R and display it
```
Desired output
The desired output is that which one gets from manually copying over the code from start.R and plot.R into the code chunks in notebook.Rmd. This looks like this (some missing due to lack of screen space):
Things I've tried
source
This loads the code, but does not display it. It just displays the source command:
knitr::read_chunk
This command was mentioned here, but actually it does the same as source as far as I can tell: it loads the code but displays nothing.
How do I get the desired output?
The solution is to use knitr's chunk option code. According to knitr docs:
code: (NULL; character) if provided, it will override the code in the
current chunk; this allows us to programmatically insert code into the
current chunk; e.g. a chunk option code =
capture.output(dump('fivenum', '')) will use the source code of the
function fivenum to replace the current chunk
No example is provided, however. It sounds like one has to feed it a character vector, so let's try readLines:
```{r start, code=readLines("start.R")}
```
```{r plot, code=readLines("start.R")}
```
This produces the desired output and thus allows for a modularized project structure.
Feeding it a file directly does not work (i.e. code="start.R"), but would be a nice enhancement.
For interoperability with R Notebooks, you can use knitr's read_chunk method as described above. In a notebook, you must call read_chunk in the setup chunk; since you can run notebook chunks in any order, this ensures that the external code will always be available.
Here's a minimal example of using read_chunk to bring code from an external R script into a notebook:
example.Rmd
```{r setup}
knitr::read_chunk("example.R")
```
```{r chunk}
```
example.R
## ---- chunk
1 + 1
When you execute the empty chunk in the notebook, code from the external file will be inserted, and the results displayed inline, as though the chunk contained that code.
As per my comment above, I use the here library to work with projects in folders:
```{ r setup, echo=FALSE, message=FALSE, warning=FALSE, results='asis'}
library(here)
insert <- function(filename){
readLines(here::here("massive_report_folder", filename))
}
```
and then each chunk looks like
```{ r setup, echo=FALSE, message=FALSE, warning=FALSE,
results='asis', code=insert("extra_file.R")}
```

R Markdown - variable output name

With one R markdown file, I would like to create different possible output pdf documents, where the output file name should be defined within the document. Is there any way to convince markdown to manipulate the output filename in such a way? Ideally I would like to pass the filename by an r chunk.
You can keep the simplicity of using the RStudio Knit button and reproducibility of a YAML header by using the undocumented knit hook to redefine what the button does (default function called is rmarkdown::render). The output_file parameter of the render function specifies the file name, so by setting it you override the standard behaviour of using the same prefix as the input filename.
e.g. to always output a file called myfile.pdf
knit: (function(inputFile, encoding) { rmarkdown::render(inputFile, encoding = encoding, output_file = file.path(dirname(inputFile), 'myfile.pdf')) })
The function can be an anonymous one-liner as well as imported from a package, as seen here with slidify.
You can set your own YAML headers (I don't know if this is generally advised anyway), accessible under rmarkdown::metadata$newheader but they don't seem available from within this sort of function as far as I can see.
As for passing file name in from an R chunk... if you're referring to code chunks below the YAML header, from my experience I don't think that's possible(?). Headers can contain inline R commands (single backtick-enclosed, starting with r), but seemingly not for this hook function.
Related:
Rmarkdown GitHub repo issue — output format-specific output_file
Blog post I wrote following this question [invalid link, domain for sale as of 20210216] / corresponding GitHub wiki notes
This is pretty much what I do:
rmarkdown::render('my_markdown_report.Rmd',
output_file = paste('report.', Sys.Date(),
'.pdf', sep=''))
I have three scripts - one pulls the data and process it, second created charts & tables for report. Third one creates report based on markdown file. Code you see above is the part of the third script
I played around with the Knitr-hook without fully understanding how it works and ran into an ugly workaround. The below coding seems to do the trick.
Would be nice if somebody can either explain why it works and/or if it can written less ugly.
For now I lost the shiny input screen but believe this can even be added later. The good thing is that the R-Studio Knit button can still be used.
Please note that the subtitle and the file name are both: This Works! even with space and exclamation mark. The file is saved as This Works!.pdf
The filename and subtitle are set by assigning the text to the object pSubTitle.
Note that the params are still in the YAML but are not resulting in a shiny popup screen as they are assigned in the Knitr-hook
---
params:
sub_title:
input: text
label: Sub Title
value: 'my_Sub_Title_and_File_Name'
title : "Parameterized_Title_and_output_file"
subtitle : "`r params$sub_title`"
output:
pdf_document:
keep_tex: false
knit: (
function(inputFile, encoding) {
pSubTitle <- 'This Works!'
rmarkdown::render(
input = inputFile,
encoding = encoding,
params = list(sub_title = pSubTitle),
output_file = pSubTitle) })
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## R Markdown
This is an R Markdown document. ....
My current solution for this and similar questions is through 2 scripts:
Script1: "xxx.md" file with flexible yaml header, similar to Floris Padt's. This header allows you to generate flexible pdf files with specified title, dates, and other features if you change the params. However, it could not specify flexible pdf names when you render it.
---
params:
feature_input: "XXXA"
date: "08/18/2022"
title: "`Test For `r params$feature_input``"
author: "You Name"
date: "`r params$date`"
output:
pdf_document:
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## R Markdown and data process
```
#Get parameter from yaml head
input_para <- params$feature_input
input_para
```
Script2: "YYY.R", which specify params in xxx.md file, and specify pdf file names by output_file when rendering.
featureNames <- c("aaa", "bbb", "ccc")
setwd("path to xxx.md")
for (currentFeature in featureNames) {
rmarkdown::render("xxx.Rmd",
params = list(feature_input = currentFeature,
date = Sys.Date()),
output_file=paste0("output/",currentFeature))
}
You could update featureNames in yyy.R file, and run yyy.R to get the most flexible use of your xxx.md file.
This solution allows you to:
update yaml header parameters,
apply updated yaml parameters in your .md code chunk,
and save your pdf with specific and flexible names.

Using knitr to create HTML slide with separate output of just the R code

I am using knitr to create a set of lecture slides for a class using R. I would like to create a separate "companion file" that contains just has the R code (corresponding to the slides), so that students can execute the R code by cutting and pasting from the companion file.
For example, in the .Rmd file:
``` {r ....}
plot(x,y)
```
Then there would be a text file with:
plot(x,y)
But, have such a file be automatically produced from the .Rmd file?
Even better if the .Rmd file has such tags:
``` {r basic.plot ....}
plot(x,y)
```
Then, text file has:
# basic.plot
plot(x,y)
Can this be accomplished using knitr?
Yes, this is possible. What you're trying to do is called tangling, and it comes from the world of literate programming.
The knit function supports a tangle option that should be set to TRUE if you want to extract source code.

Resources