Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Source nested R files within Rmarkdown document

I am writing a Rmd report with some R code chunks, obviously. My code structure is like the following:

  • A functions.R script for custom functions
  • DataDependency.R script for loading packages and my data, this already sources functions.R for exactly these tasks
  • Some analysis.R scripts sourcing DataDependency.R
  • Some more furtheranalyis.R sourcing analysis.R, since then I don't have to write some steps multiple times

Therefore, I am heavily depending on the function to source files in a nested way. However, I am unable to accomplish this in RMarkdown which gives me errors every single time (see below). Am I too stupid or is this functionality missing?! All tries so far resulted in error.

The other questions I saw regarding the topic only included sourcing of .Rmd within .Rmd files (here) and the distinction between source() and read_chunk() (here). Both do not answer my question.

I already tried to make sure that it is really the nested sourcing that produces the errors. So here is a minimal working example:

MWE

File mweA.R

x = 1:10

and file mweB.R

source("./mweA.R")
y = x * x

Now, in my .Rmd file I want to just load file B (or both if I must) and then get on with it:

```{r}
source("./mweB.R")
plot(y ~ x)
```

And even if I do this:

```{r}
source("./mweA.R")
source("./mweB.R")
plot(y ~ x)
```

the same error occurs, namely:

Error in file(filename, "r", encoding = encoding) : cannot open the connection Calls: <Anonymous> ... source -> withVisible -> eval -> source -> file Execution halted

Please note that I don't get an error, if I just do source("./mweA.R") or source any other non-depending R script.

Hopefully, there is a (more or less) secret parameter that you have to specify in the chunk which solves all this. I really have a hard time with Rmarkdown's code chunks and it is often not clear to me, what the error is. This mainly keeps me from switching from latex to RMarkdown...

like image 964
bamphe Avatar asked Feb 08 '18 11:02

bamphe


1 Answers

The issue you're facing is not related to knitr or being able to correctly nest the documents but is instead a product of the R project "working directory insanity" one faces as rmarkdown will knit the document relative to the file directory as opposed to the project root. This leads to different relative paths depending on whether the document is run in the project session or knitr session.

In addition to the gist, this issue shows a number of workarounds:

knitr specific:

Set a root directory for all chunks to be evaluated relative to rather than the document location.

opts_knit$set(root.dir = '/Users/username/path_to_project')

General case:

Use either rprojroot or here (the latter is a wrapper over the former), which uses several criteria to determine the top level directory of your files. You need not be using an RStudio project for this to work.

Any reference to another local file is called using here::here which will resolve to the same location regardless of the subdirectory in which it's called.

source(here("functions.R"))
source(here("subdirectory", "DataDependency.R"))
source(here("subdirectory2", "furtheranalyis.R"))

This is probably a better solution as it doesn't rely on knitr options. Alternatively you can set the root.dir chunk using rprojroot:

opts_knit$set(root.dir = rprojroot::find_rstudio_root_file())

provided you are using an RStudio project. If not, use rprojroot::find_root with a specified criterion.

like image 114
ruaridhw Avatar answered Sep 25 '22 09:09

ruaridhw