4

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.

Eric Green
  • 7,385
  • 11
  • 56
  • 102
  • don't know, but why don't you instrument your `.rmd` file further by adding `getwd()` calls in each chunk? – Ben Bolker Nov 09 '13 at 21:04
  • @BenBolker, I added `wd <- getwd()` just before `opts_knit$set(root.dir=wd)`. i don't understand why, but now 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. do you know why `wd` changes from `mypath/testknit` to `mypath/testknit/scripts` when running `knit("scripts/test.rmd")` from `master.R`? – Eric Green Nov 10 '13 at 01:30
  • 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. – Yihui Xie Nov 10 '13 at 07:07
  • No problem. Just let me know if this blind shot in the dark works :) – Yihui Xie Nov 10 '13 at 19:31
  • 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! if you create an answer i'll select it. – Eric Green Nov 11 '13 at 12:37

1 Answers1

4

@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!

Nikos Alexandris
  • 708
  • 2
  • 22
  • 36
Eric Green
  • 7,385
  • 11
  • 56
  • 102