Eric Green
Eric Green

Reputation: 7725

trouble finding file source in .rmd chunk when knitting .rmd from master .R file

Let's say I have a project directory called testknit (and I do, see github for MRE), and inside this I have several subdirectories, including scripts where I keep .R and .rmd files.

In RStudio, I create a project and select this testknit directory so that when I open the project, the working directory is mypath/testknit.

Inside testknit/scripts I have a master.R file. If I want to source a file called testsource1.R, which is also in testknit/scripts, I can run source("scripts/testsource1.R") from within master.R.

library(knitr)
getwd()
# [1] "mypath/testknit"
source("scripts/testsource1.R")

So far so good.

But let's say I also want to knit a .rmd file called test.rmd that is located in testknit/scripts. I can run knit("scripts/test.rmd") from master.R.

My test.rmd file does the following:

```{r setup}
  library(knitr)
  opts_knit$set(root.dir='../')
```

```{r option1}
  source("scripts/testsource2.R")
```

```{r option2}
  source("testsource2.R")
```

Since test.rmd exists within testknit/scripts, I specify opts_knit$set(root.dir='../') in the first chunk so knitr knows that my root directory is really one level up.

When I open test.rmd in RStudio and click knit HTML, predictably, the option1 chunk works and the option2 chunk does not.

But when I try to knit test.rmd by running knit("scripts/test.rmd") from master.R instead of knitting from within the .rmd file, neither chunk option works. Both return an error that there is no file by that name.

What am I doing wrong? Why can't R find testsource2.R when knitting the .rmd file from the master .R?

See github link above for reproducible example.

Update:

As I noted below in the comments, I tried adding wd <- getwd() just before opts_knit$set and changed (root.dir='../') to (root.dir=wd). So when I run knit("scripts/test.rmd") from master.R, the option2 chunk runs because the wd I added gets set to mypath/testknit/scripts. But if i open the .rmd file and run all chunks, wd is set to the root directory, mypath/testknit, and the option1 chunk runs.

I need the working directory to remain the project root. This does not seem like an elegant solution to me, but changing:

```{r setup}
  library(knitr)
  opts_knit$set(root.dir='../')
```

to

```{r setup}
  library(knitr)
  wd <- ifelse(basename(getwd())=="scripts", 
               gsub("/scripts", "", getwd()),
               getwd())
  opts_knit$set(root.dir=wd)
```

lets me run all chunks when in the .rmd file or knit("scripts/test.rmd") from master.R. It works, but it feels like I am taking the wrong approach.

Upvotes: 4

Views: 2353

Answers (1)

Eric Green
Eric Green

Reputation: 7725

@Yihui: Perhaps you can make ../ an absolute path using normalizePath('../'). A relative working directory can be confusing to reason about (at least my head hurts after I read too many levels of relative paths :). BTW, when you Knit HTML in RStudio, RStudio first changes the working directory to the input Rmd file.

Me: yes! using just opts_knit$set(root.dir=normalizePath('../')) works for knitting the .rmd file from master.R and knitting to html or running all chunks from within the .rmd. I updated the github example. test-b.rmd now shows this. thanks!

Upvotes: 4

Related Questions