Включить код из файла в RMarkdown, когда имя файла является переменным - PullRequest
3 голосов
/ 17 февраля 2020

Я хочу иметь блок R в RMarkdown, который включает код из внешнего файла.

Я хочу включить файл, а не встраивать его содержимое напрямую, поскольку внешний файл содержит код, который совместно используется различными проектами и сценариями, и я хочу быть уверенным, что каждая программа использует самую последнюю версию. Для этого предусмотрена опция чанка code = ....

Следующий метод отлично работает , если Я вяжу весь документ. Однако, если я пытаюсь запустить отдельные чанки в Rstudio (как требуется во время разработки), я получаю сообщение об ошибке "Error in readLines(include_file) : object 'include_file' not found".

Как мне заставить это работать, чтобы я мог запускать чанки из Rstudio?

Воспроизводимый пример:

Сначала создайте несколько включаемых файлов

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')

Затем поместите следующее в файл .Rmd

---
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)
```

Это то, что выводится выглядит, когда я вяжу весь документ

enter image description here

1 Ответ

1 голос
/ 18 февраля 2020

Предполагается, что у вас есть файл source.R со следующим содержимым:

# 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

Затем вы сначала должны прочитать файл:

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

, затем вы можете вызвать куски кода из исходного файла, например, так:

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

Обратите внимание, что все может быть в одном и том же фрагменте кода, но read_chunk() должен быть вызван до <<cc_1>>, и как в этом случае <<cc_2>> требует tmp <<cc_1>> должен быть вызван до <<cc_2>>.

Кстати, если вы хотите молча оценить кучу кода, вы можете использовать include = FALSE, например,

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

, тогда вы можете вызвать элемент из <<cc_1>>, например

```{r}
print(tmp)
```
...