Changing the output directory for Quarto projects in Rstudio - directory

I am transitioning from using Rmarkdown to Quarto files within R projects. When using Rmarkdown I was able to direct my output file in a specific directory to reduce clutter.
For example, my project structure usually takes the form:
$
│ demo_proj.Rproj
│ _quarto.yml
│
├─-quarto
│ test_render.qmd
│
├─-output
│ test_render.pdf
│
└─-data
cars.csv
In Rmarkdown I could just insert the following lines in the YAML and the knitted file would be placed in the output directory (as above).
knit: (function(input, ...) {
rmarkdown::render(
input,
output_dir = "../output"
)
})
Is there a similar possible solution when using Quarto projects?
I've tried adding:
project:
title: "r_thesis"
output-dir: output
to the _quarto.yml, which sorts of works but with two annoying consequences.
The knitted file is saved in a directory named quarto within the output folder
The local host browser in which the knitted file should be open cannot find the file, meaning I have to open them manually every time I knit.
Does anyone know of any solution to this very minor but annoying problem?

Related

Find the right path of child document in r markdown

I got one code from a colleague, and I want to modify it for my purpose. It's a bookdown project. In the index.Rmd file, there is a code
r child = here::here("prelims", "00--prelim.Rmd")
This means, in the working directory, there is a folder called "prelims" and the child document "00-prelims.Rmd" exists in that "prelims" folder. I can knit the index.Rmd document with this code, when this index.Rmd is part of a folder. But if I have created an RStudio project, then the location of "00-prelims.Rmd" changes.
If projectname.Rproj file exists, then the location of the "00-prelims.Rmd becomes here::here("projectname","prelims","00-prelims.Rmd").
So, I have tried the following
r child = ifelse(file.exists(Sys.glob("*.Rproj")),here::here(sub("\\..*", "", list.files(pattern = "\\.Rproj$")),"prelims", "00-prelims.Rmd"),here::here("prelims", "00-prelims.Rmd"))
But it gives me logicl(0) error. How can I get the right path of the "00-prelims" file every time?

R - Knit HTML output in wrong directory

When I knit my .Rmd file to HTML, instead of saving the output to the same directory as the .Rmd file, RStudio saves the .html file and a copy of the original .Rmd file to my home directory instead of my working directory. Any idea how to fix this? Purely for organization purposes I'd like the output to be in the same directory as the oringinal .Rmd file.
I'd suggest using Dean Aatali's ezknitr package, which he wrote to correct this and a few other infelicities of knitr's input and output directory defaults. ezknitr::ezknit() "just works" as you'd like it to, writing its outputted HTML file to the directory contain the markdown file, instead of (as knitr::knit() would) to the current working directory:
## Reproducible e.g.
dir.create("path/to", recursive=TRUE)
cat("Hello world", "path/to/eg.Rmd")
## Check how it works
ezknitr::ezknit("path/to/eg.Rmd")
dir("path/to/")
[1] "eg.html" "eg.md" "eg.Rmd"

How can I avoid hardcoding a file path?

I am using RStudio to knit an .Rnw file to .pdf. This .Rnw file is stored in directory that is under git version control. This directory also contains a .RProj file for the project.
I collaborate with colleagues who don't know the first thing about .Rnw files and git. These colleagues want to open a Word file and track change their hearts out. So I give the people what they want.
Everyone needs access, so storing the Word file on a cloud service like Box makes sense. In the past I created a subfolder in my repo that I shared—keeping everything within the root directory—but this time around I needed to store the file in a shared folder that someone else created. So my solution was to copy the Word file from this shared directory to my repository.
Technical Approach
I don't know how to make this a reproducible problem, but hopefully you will give me some latitude since I'm trying to make my work fully reproducible ;)
Let's say that my .Rnw file is stored in repoRoot/subfolder. Since knitr changes the working directory to subfolder where this .Rnw file is located, the first chunk sets the root.dir one level up at the project root.
<<knitr, include=FALSE>>=
library(knitr)
opts_knit$set(root.dir=normalizePath('../')) # go up 1 level
#
The next chunk copies the Word file from the shared folder to my git repo and runs the analysis file. The shared directory path is hard coded to my machine, which is the problem I'm writing for your help solving.
file.copy(from='/Users/ericpgreen/Box Sync/Project/Paper/draft.docx',
to='subfolder/draft.docx', # my repo
overwrite=TRUE)
source(scripts/analysis.R) # generates objects we reference in the .docx file
After adding \begin{document}, I include a chunk where I convert the .docx file to .txt and then rename it to .Rnw.
# convert docx to txt
system("textutil -convert txt 'subfolder/draft.docx'")
# rename txt to .Rnw
file.rename('subfolder/draft.txt',
'subfolder/draft.Rnw')
The next child chunk calls this .Rnw file that contains the text of the Word file with references to R objects included through \Sexpr{}:
<<include-draft, child='draft.Rnw', include=FALSE>>=
#
This works just fine for me. Whenever I knit the .Rnw file it grabs the latest version of the .docx file that my colleagues have edited (complete with track changes and comments) and, in a later step not shown here, returns the .pdf file to the shared folder.
Problem to Solve
This setup meets almost every need for me, except that the initial file.copy() command is hard coded to my machine. So if someone in my group clones my repo (e.g., research assistants who DO use version control), it won't run out of the box. Is there a workaround to hard coding in this type of case?
Ultimately you won’t get around hard-coding paths that are outside your control, such as paths to network shares. What you can and should avoid is hard-coding these paths in your documents.
Instead, relegate them to configuration files and/or environment variables (which, again, will be controlle by configuration files, to with .bashrc and similar). The simplest approach is then to use
network_share_path = Sys.getenv('NETWORK_SHARE_PATH',
stop('no network share path configured'))
file.copy(from = network_share_path, to = 'subfolder/draft.docx', overwrite = TRUE)

How to import knitr cache into the global environment of R session [duplicate]

I have an Rmd file with a lot of cached code chunks.
Now I want to keep developing that script using an interactive session to play around and test different solutions before putting the final code in a new chunk of the document.
With a plain R script, I could just source it to get my interactive session on par with the last line of the script.
However, this would result in (re-)executing all code within the interactive session.
I want to read my Rmd file into an interactive session ignoring the Markdown part & making use of the existing knitr cache, ideally without creating any output.
How can I do this?
PS: I am not looking for some IDE-specific way to set this up but for a command that I can run from a simple R session in any terminal emulator.
I've created functions load the objects from cached chunks into an interactive R session. The functions are lazyload_cache_dir and lazyload_cache_labels and are available in qwraps2 version > 0.2.4
A detailed example of the use of these functions is
here:
Quick overview:
Say you have the file report.Rmd
---
title: "A Report"
output: html_document
---
```{r first-chunk, cache = TRUE}
fit <- lm(mpg ~ wt + hp, data = mtcars)
x <- pi
```
```{r second-chunk, cache = TRUE}
fit <- lm(mpg ~ wt + hp + am, data = mtcars)
xx <- exp(1)
```
After knitting you end up with a this project directory
.
├── report_cache
│ └── html
│ ├── first-chunk_bf368425c25f0c3d95cac85aff007ad1.RData
│ ├── first-chunk_bf368425c25f0c3d95cac85aff007ad1.rdb
│ ├── first-chunk_bf368425c25f0c3d95cac85aff007ad1.rdx
│ ├── __packages
│ ├── second-chunk_2c7d6b477306be1d4d4ed451f2f1b52a.RData
│ ├── second-chunk_2c7d6b477306be1d4d4ed451f2f1b52a.rdb
│ └── second-chunk_2c7d6b477306be1d4d4ed451f2f1b52a.rdx
├── report.html
└── report.Rmd
and you want to load the objects from first-chunk.
lazyload_cache_labels("first-chunk", path = "report_cache/html")
## Lazyloading report_cache/html/first-chunk_bf368425c25f0c3d95cac85aff007ad1
ls()
## [1] "fit" "x"
See the blog post for details on loading only a whole directory of cached objects or loading specific objects from within a cached chunk.
Internally, knitr uses lazyLoad to load cached results, and so can you:
lazyLoad('knitr_cache_dir/chunk_2c7d6b477306be1d4d4ed451f2f1b52a')
Make sure to supply the filename without the suffix.
I think that running library("knitr"); knit("foo.Rmd") in the console/R session is the easiest way to do this, although it will rewrite foo.md, figures, etc.. (Too busy/lazy to test it at the moment.)
You could probably poke around in the cache directory and read the cached files directly, but that would be a lot more work/trickier.

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}

Resources