Параметризация невыполненного блока кода в Rmd - PullRequest
2 голосов
/ 28 марта 2019

Я работаю над документом .Rmd, где мы показываем людям, как использовать командную строку. Это включает в себя блоки кода на основе bash, такие как:

```{bash}
echo "this is a test"
```

Тем не менее, мы хотели бы параметризовать это, поэтому что-то вроде

---
params:
    testparam: "this would echo something else"
---

```{bash}
echo params$testparam
```

Однако это не работает, потому что внутри блока кода bash параметры не существуют. Есть ли способ использовать параметры в таких случаях, по сути, оценивая params$testparam до того, как knitr учитывает тот факт, что он находится внутри блока кода не-R?

В идеале решение должно сделать возможным следующее:

```{bash}
echo params$testparam
```

превращается в

<pre class="bash"><code>echo "this would echo something else"
## this would echo something else

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

Как я и надеялся, этот маленький хак сработает:

---
params:
    testparam: "this would echo something else"
---

```{r, echo = FALSE, include = FALSE}
if (length(params) > 0) do.call(Sys.setenv, params)
```

```{bash}
echo $testparam
```

Уступая

<pre class="bash"><code>echo $testparam
## this would echo something else

Это не удастся, если вы передадите непростые объекты. Я не тестировал векторы / списки / фреймы, хотя подозреваю, что они не получатся эффектно ... но поскольку вы используете bash в этом фрагменте, я предполагаю, что его параметры менее сложны.

Если у вас есть несколько сложных параметров, которые никогда не будут использоваться в ваших bash-фрагментах, вы можете рассмотреть соглашение об именах, например:

---
params:
    bashtestparam: "this would be one thing"
    testparam: "this would echo something else"
---

```{r, echo = FALSE, include = FALSE}
p <- params[ grepl("^bash", names(params)) ]
names(p) <- gsub("^bash", "", names(p))
if (length(p) > 0) do.call(Sys.setenv, p)
```

```{bash}
echo $testparam
```

что дает

<pre class="bash"><code>echo $testparam
## this would be one thing
1 голос
/ 28 марта 2019

Следующие .Rmd могут быть достаточными?Я использую system() в блоке R:

---
output: html_document
params:
    testparam: "this would echo something else"
---

# Header

Some text.

```{bash}
echo "this is a test"
```

Some more text.

```{r}
cat(system(paste0("echo '", params$testparam, "'"), intern = TRUE), sep = "\n")
```

enter image description here

Сильное вдохновение от здесь. Конечно, команда bash плохо видна, но я подозреваю, что можно обойти это.

РЕДАКТИРОВАТЬ:

С небольшим количеством обходного пути / хак, выможет отобразить код bash следующим образом:

```{r bashCode, results="asis", echo=FALSE}
bash_code <- sprintf("echo '%s'", params$testparam)
cat("<pre class='bash'><code>",
    bash_code,
    "
")` `` `` `{r bashOutput, echo = FALSE} cat (system (bash_code, intern = TRUE), sep =" \ n ")`` `

enter image description here

Таким образом, мы генерируем код bash в виде character и cat кода bash, заключенного в соответствующий HTML, покауказав knitr интерпретировать результат 'asis' (чтобы результаты отображались в виде кода). Поскольку мы также подавляем сам код R (echo=FALSE), результаты отображаются только в виде кодаДалее в следующем фрагменте мы снова подавляем печать кода, но получаем вывод системной команды, которая интерпретируется стандартным способом.

Конечно, вы можете использовать трикk из @ r2evans вместе с этим.

...