Dynamically Name .Rmd Output File Based on Variable - r

Say I have an .Rmd file named "Process.Rmd", and within one chunk of the file I have a variable such as clientName <- "client AAA". Can I change the output filename from Process.pdf to Process_AAA.pdf? Specifically, the goal would be that I can simply change the clientName variable, strsplit() the client name, and use the second index of the split string in the filename.
eg. if I change clientName <- "myclient BBB", the output file would be Process_BBB.pdf.
I've tried changing the knit hook in the YAML header (example below), but I get errors because the clientName hasn't yet been defined.
title: "Process"
author: '***'
date: "`r format(Sys.time(), '%B %Y')`"
output:
pdf_document:
template: "/path/to/template.tex"
keep_tex: true
latex_engine: xelatex
knit: (function(inputFile, encoding) {
rmarkdown::render(inputFile,
encoding=encoding,
output_file= "`r paste0(
'Process_',
strsplit(clientName, ' ')[[1]][2],
'.pdf'
)`"
) })
When I move the knit hook to a portion of the .Rmd file after the clientName is defined, the output filename doesn't change.
I've also thought about creating a separate .R script with a function to render the document, but I need to reference the client name that's set in the .Rmd file; I haven't been able to source() a variable in that script from the .Rmd file...
Open to any suggestions

Related

Bookdown Download for HTML single document

I have a bookdown book with multiple output formats.
I want the user to be able to download the content in multiple formats. This works wonders with PDF, EPUB and so on. But it does not work with single file HTML bookdown::html_document2 documents as they are rendered in the present working directory . and not the _book folder.
E.g., when I specify bookdown::git_book: ... it gets created in _book.
When I use bookdown::pdf_book: ... it also gets created in _book.
However, when I use bookdown::html_document2: ..., it gets created in ..
Setting output_dir for the single page document didn't work.
Do you know how to solve this?
MWE
## _bookdown.yml
book_filename: "The-book"
delete_merged_file: yes
## _output.yml
bookdown::gitbook:
split_by: rmd
config:
download:
- ["The-book.pdf", "PDF"]
- ["The-book.html", "HTML"]
bookdown::html_document2:
toc: true
bookdown::pdf_book:
keep_tex: no
dev: "cairo_pdf"
latex_engine: xelatex
and then in 01-intro.Rmd
# Intro
This is a test
I make book directly from a R script and this work for me:
bookdown::render_book(
input = "index.Rmd",
output_format = "bookdown::html_document2",
output_file = "_book/The-book.html"),
)
By making the book from R script you can start to have fun with name (like adding the date) and directory of the book, noting that if the directory is not _book you will need to create it before. With pdf output you can use output_dir to have the directory created for you, but it seems not to work and even conflict with output_file for html_document2. Ex:
## PDF report
bookdown::render_book(
input = "index.Rmd",
output_format = "bookdown::pdf_document2",
output_file = paste0("Proceedings-pdf-", format(Sys.time(), format = "%Y-%m-%d-%H%M%S"), ".pdf"),
output_dir = "Proceedings"
)
## HTML
dir.create("Proceedings", showWarnings = F)
bookdown::render_book(
input = "index.Rmd",
output_format = "bookdown::html_document2",
output_file = paste0("Proceedings/Proceedings-html-", format(Sys.time(), format = "%Y-%m-%d-%H%M%S"), ".html"),
)
Quarto is able to produce stand-alone html files (https://quarto.org/docs/output-formats/html-basics.html#self-contained). E.g.
---
project:
type: book
format:
html:
embed-resources: true
---
Note that this currently does not work if you specify an output path (see here).

R markdown YAML dynamic variables

In RMarkdown, I seem to be able to create 'some' dynamic variables in the YAML header, but not for others:
For instance, this works:
---
title:
"Some Title, `r format(Sys.time(), '%d %B, %Y')`"
...
---
But this does NOT.
---
...
pdf_document:
keep_tex: `r 'true'`
---
But this DOES (ie not dynamic).
---
...
pdf_document:
keep_tex: true
---
So how can I 'dynamically' assign the keep_tex to either true or false, what I want to do, is something like this:
---
...
pdf_document:
keep_tex: `r getOption('mypackage.keep_tex')`
---
I don't know if the template options can be set programmatically in the YAML header of the .Rmd file.
As an alternative, if you use rmarkdown::render to render your document, you may specify the output template (pdf_document), and then set template options (e.g. keep_tex) programmatically.
For example, if you have a .Rmd file called "test.Rmd" like this:
---
title:
"Some Title, `r format(Sys.time(), '%d %B, %Y')`"
---
...and some logical object which determines whether to keep the intermediate TeX file or not, e.g.
my_keep <- TRUE
...you may render the input file to PDF format and keep the TeX file like this:
render(input = "test.Rmd",
output_format = pdf_document(keep_tex = my_keep))

R Markdown with Tex Header

I have created a LaTeX header file for assignments to make my R Markdown convert to PDF as desired. The header file works perfectly but has a couple of defined commands to give my name, assignment number/name and the class name.
\newcommand{\hmwkAuthorName}{Joe Bloggs}
\newcommand{\hmwkClass}{CompSci 101}
\newcommand{\hmwkTitle}{Assignment Numero Uno}
I want to be able to define these in the YAML section of my R Markdown but always getting "Undefined Control Sequence" and error 43 when converting which is remedied by putting these sections back in the header file.
This is what the YAML section looks like currently (not working):
---
title: "Assignment Numero Uno"
author: "Joe Bloggs"
header-includes:
- \newcommand{\hmwkAuthorName}{Joe Bloggs}
- \newcommand{\hmwkClass}{CompSci 101}
- \newcommand{\hmwkTitle}{Assignment Numero Uno}
output:
pdf_document:
includes:
in_header: header_temp.tex
---
How can I achieve this?
EDIT: The full header file is
\usepackage{fancyhdr}
\usepackage{lastpage}
\topmargin=-0.45in
\evensidemargin=0in
\oddsidemargin=0in
\textwidth=6.5in
\textheight=9.0in
\headsep=0.25in
\linespread{1.1}
\pagestyle{fancy}
\lfoot{\hmwkAuthorName}
\chead{\hmwkClass:\ \hmwkTitle}
\lhead{}
\cfoot{}
\rfoot{Page\ \thepage\ of\ \protect\pageref{LastPage}}
\renewcommand\headrulewidth{0.4pt}
\renewcommand\footrulewidth{0.4pt}
\setlength\parindent{0pt}
\title{
\vspace{2in}
\textmd{\textbf{\hmwkClass:\ \hmwkTitle}}\\
\vspace{3in}
}
\author{\textbf{\hmwkAuthorName}}
\date{}

Rmarkdown directing output file into a directory

I found a really nice trick (link) to a function of knitr, where you can save your output html into an output folder and under a different filename.
The only thing you have to head to the header is the following:
title: "analysis"
author: "Me"
date: "`r format(Sys.time(), '%d %B, %Y, %H:%M')`"
knit: (function(inputFile, encoding) {
rmarkdown::render(inputFile,
encoding=encoding,
output_file=file.path(dirname(inputFile), out_dir, 'analysis.html')) })
output:
html_document:
number_sections: yes
toc: yes
This works on my Mac 'sometimes' very well, but sometimes it has problems to find the out_dir variable...
I first thought about executing the chunks first, so the variable is set... But this didn't solved the problem...
I also restarted R session and this didn't helped.
The last step was closing R, saving the workspace and after reopening R and loading workspace it works like a charm again.
I could not find the original post, where somebody recommended this trick...
EXACT WORKFLOW TO REPRODUCE
open new project, name it test in a new folder
create a r markdown document
change the header to:
---
title: "Untitled"
author: "Me"
date: "`r format(Sys.time(), '%d %B, %Y, %H:%M')`"
knit: (function(inputFile, encoding) {
rmarkdown::render(inputFile,
encoding=encoding,
output_file=file.path(dirname(inputFile), out_dir, 'analysis.html')) })
output:
html_document:
number_sections: yes
toc: yes
---
```{r write quant output files}
out_dir <- 'test'
if(!file.exists(out_dir)) {
dir.create(out_dir)
}
```
save the document as test.Rmd
click the knit button (html is now removed from the options of the button)
This will fail!
Close the project!
Click on save environment!
Open the Project and click knit!
Everything works.
execute rm(list=ls()) everything works afterwards again
You could try setting the out_dir variable in the function you are giving knit to render:
knit: (function(inputFile, encoding) {
out_dir <- 'test';
rmarkdown::render(inputFile,
encoding=encoding,
output_file=file.path(dirname(inputFile), out_dir, 'analysis.html')) })
I found it cumbersome to write the output-file name so I swapped the output_file to output_dir argument but kept the rest of the code. In this way my Rmarkdown is still knitted into a subdirectory but with the inputFile name. Also, if the directory does not exist, it is created
---
title: "title"
author: "gordon freeman"
date: "`r Sys.Date()`"
knit: (function(inputFile, encoding) {
out_dir <- "reports";
rmarkdown::render(inputFile,
encoding=encoding,
output_dir=file.path(dirname(inputFile), out_dir))})
---

Rmarkdown: different output folders, shared libs

I have an .R file wherein I for each unique value in a list, render a number of different .Rmd files. Something like this:
for (uddannelse in unique(c("Monkey","Horse"))) {
rmarkdown::render("file1.Rmd", output_dir=file.path(getwd(), uddannelse) ,output_file=paste("file1", uddannelse,".html", sep="_"), encoding="UTF-8")
rmarkdown::render("file2.Rmd", output_dir=file.path(getwd(), uddannelse), output_file=paste("file2", uddannelse,".html", sep="_"), encoding="UTF-8")
}
As evident by the render parameters, the html-output should go into a separate folder for each value in the list, in the above example: folder: "Monkey" and folder "Horse".
Each .Rmd file has the following front matter (the files go to a static html website and needs to have self_contained: false:
---
output:
html_document:
theme: readable
self_contained: false
lib_dir: pub/libs
css: pub/libs/custom_css/custom.css
date: "`r format(Sys.time(), '%d %B, %Y')`"
---
However: When I call the render functions I recieve this error:
Error in relativeTo(basepath, dir) :
The path C:/Users/ac/Dropbox/2014_07_WIP/pub/libs/jquery-1.11.0 does not appear to be a descendant of C:/Users/ac/Dropbox/2014_07_WIP/Monkey/
So I guess the rmarkdwown::render first creates the lib directories relative to the Rmd file, yet expect the files to be placed relative to the output files.
How can I get around this, so that I can have a set of common Rmd input files in one folder, and have output in different folders, yet share a common lib?
I tried to place something like this in the fronmatter.
---
output:
html_document:
theme: readable
self_contained: false
lib_dir: "`r file.path(uddannelse, "libs")`"
css: "`r file.path(uddannelse, "libs", "custom_css", "custom.css")`"
date: "`r format(Sys.time(), '%d %B, %Y')`"
---
And I got this error:
Error in yaml::yaml.load(front_matter) :
Parser error: while parsing a block mapping at line 3, column 5did not find expected key at line 5, column 50
I solved my immediate problem by passing some of the front matter in the render call:
rmarkdown::render("file1.Rmd",
output_dir=file.path(uddannelse),
output_file=paste("file1", uddannelse,".html", sep="_"),
output_options=list(html_document =
list(self_contained = FALSE,
lib_dir = file.path(uddannelse, "lib"),
css = paste("lib", "custom_css", "custom.css",
sep="/"),
include = list(
after_body = file.path(uddannelse,
"footer_w_index.html")))),
encoding="UTF-8")
Notice that lib_dir has to be relative to the Rmdfile and css has to be relative to the output-file.
For some reason - regardless of whether I use paste or file.path(fsep="/", ...) the css path in the output file is linked with windows separator ("\") - and thus not usable in e.g. Firefox.

Resources