6

I want to have an R chunk in RMarkdown that includes code from an external file.

I want to include the file, rather than embed its contents directly, because the external file contains code that is shared between various projects and scripts, and I want to be sure that each program uses the most recent version. The code = ... chunk option is made for this.

The following method works fine if I knit the whole document. However, if I try to run the individual chunks inside Rstudio (as required during development) I get an error "Error in readLines(include_file) : object 'include_file' not found".

How do I get this to work so I can run chunks from within Rstudio?

Reproducible example:

First create some include files

write_lines("x = 1", 'include_1.r')
write_lines("x = 2", 'include_2.r')
write_lines("x = 3", 'include_3.r')
write_lines("x = 4", 'include_4.r')

Then put the following into a .Rmd file

---
title: "Untitled"
output: html_document
---

```{r setup}
knitr::opts_chunk$set(echo = TRUE)
include_file = list.files(pattern = '^include_.+[Rr]$')
include_file = include_file[which.max(file.info(include_file)$mtime)]
```

I want to embed an R code from a file like this:

```{r, code = readLines(include_file)}
```

Then use the objects from the include file

```{r}
print(x)
```

This is what the output looks like when I knit the whole document

enter image description here

dww
  • 30,425
  • 5
  • 68
  • 111
  • You wouldn't want to just source the scripts within a chunk? – camille Feb 17 '20 at 17:12
  • Thanks @camille - yes that would avoid the error, but then you don't get to see the sourced code in the output document. – dww Feb 17 '20 at 17:14
  • Ahh I see. And I guess it would be too redundant to source in one chunk and call `readLines` in another... – camille Feb 17 '20 at 17:19
  • Actually that's the current cludge I'm using right now. Hoping for something neater and more idiomatic. – dww Feb 17 '20 at 17:25
  • See this previous issue https://stackoverflow.com/questions/15501622/making-knitr-run-a-r-script-do-i-use-read-chunk-or-source that points to this https://yihui.org/knitr/demo/externalization/. – Kevin Cazelles Feb 18 '20 at 02:00

1 Answers1

2

Assuming you have a file source.R with the following content:

# first code chunk to be included
## @knitr cc_1
var1 <- runif(10)
var2 <- runif(10)
tmp <- sum(var1)
## @knitr end_cc_1

# second code chunk to be included
## @knitr cc_2
prod(var1, var2)
## @knitr end_cc_2

Then you first have to read the file:

```{r}
knitr::read_chunk("source.R")
```

then you can call the code chunks from the source file like so:

```{r}
<<cc_1>>
print(tmp)
<<cc_2>>
```

Note that everything can be in the same code chunk but read_chunk() must be called before <<cc_1>> and as in this case <<cc_2>> requires tmp <<cc_1>> must be called before <<cc_2>>.

BTW if you want to evaluate a bunch of code silently you can use include = FALSE, e.g.

```{r include = FALSE}
<<cc_1>>
```

then, you can call element of <<cc_1>>, e.g.

```{r}
print(tmp)
```
Kevin Cazelles
  • 1,255
  • 9
  • 20
  • 1
    Thanks, I was aware of `read_chunk`, (and use it with Lyx). Unfortunately it's not compatible with caching, afaik. Hence the desire to use `code =` instead. – dww Feb 18 '20 at 14:01
  • I see, so it's as if you cannot use the first code chunk to run the second unless you knit the entire document, right? – Kevin Cazelles Feb 18 '20 at 14:29
  • 1
    Also, I tested this and it does not allow you to run the individual chunks interactively in Rstudio. Only seems to work when you knit the whole document... so doesn't answer the qestion unfortunately. Thanks anyway. – dww Feb 19 '20 at 19:04