6

I am using knitr for making a markdown report for some bash commands. However, my operations include changing a directory and creating a file there, so it would be ideal if I could use cd in my .Rmd file:

make a directory
```{r mkdir, engine='bash'}
mkdir mytest
```
cd into directory
```{r cd, engine='bash'}
cd mytest
```
create file
```{r create, engine='bash'}
touch myfile
```
check contents
```{r ls, engine='bash'}
ls
```

However, the file myfile is created in the directory from which I compile the document with knit and not in mytest. I guess a new bash shell is started for each code chunk.

I have seen discussions about setting cwd in R (https://github.com/yihui/knitr/issues/277) but not for bash.

Is there a way of maybe setting a working directory for a code chunk?

user1981275
  • 13,002
  • 8
  • 72
  • 101
  • 1
    Did you take a look at `opts_knit$set(root.dir = "...")` and `setwd("...")`? – pfuhlert May 19 '15 at 13:20
  • Yes, but these are both R functions and I do not have any R code in my chunks. I am only using R to call `knit`. So I do not see a possibility to change cwd between chunks... – user1981275 May 19 '15 at 13:34
  • 2
    That is a known problem. Please see the last paragraph of http://yihui.name/knitr/demo/engines/ Also see https://github.com/yihui/runr I'm not quite sure if runr still works well in terms of the `bash` engine. – Yihui Xie May 19 '15 at 20:00
  • Thanks! I will have a look at runr – user1981275 May 20 '15 at 10:02

2 Answers2

0

You may use Rscript to run a .Rmd file and include any "R code" within the command line to keep your code chunks intact.

Rscript -e "library(knitr); opts_knit\$set(root.dir='~'); knit('test.Rmd')" is an example bash command to run the test.Rmd file below. You may change the root.dir to suit your needs.

make directories
```{r mkdir, engine='bash'}
mkdir mytest
mkdir mytest2
```

create one file in the 1st dir
```{r create, engine='bash'}
cd mytest
touch myfile
```

create another file in the 2nd dir
```{r create2, engine='bash'}
cd mytest2
touch myfile2
```

check contents
```{r ls, engine='bash'}
ls mytest*
```

The output:

```
## mytest:
## myfile
##
## mytest2:
## myfile2
```
xb.
  • 1,617
  • 11
  • 16
  • he root.dir set in the options here has no effect; your solution creates the files within the created directories because `cd` and `touch` are in the same code chunk. – user1981275 May 20 '15 at 10:08
  • I see same problem you mention, @user1981275. the dir never changes, everything stays in document directory. – pauljohn32 Nov 14 '16 at 18:38
0

Another way of looking at it would be to create every folder and file from where you are, and not move around with cd.

Create a directory tree

mkdir accepts more than one argument

mkdir -p 'plots/scatter' 'plots/box'
# creates plots folder in the working directory,
# and then creates scatter and box folders in it.

Create files in there

touch 'plots/scatter/firstfile.txt' 'plots/scatter/secondfile.txt'
# single quotes mean literals

Keep key parts as variables

To easily change the folder structure from a one central variable:

scatter_folder=plots/scatter
touch "$scatter_folder/third_file.txt" "$scatter_folder/fourth_file.txt"
# double quotes allow for variable substitution.
Taavi
  • 135
  • 2
  • 16