参数化 Rmd 中未执行的代码块

Parameterize non-executed code block in Rmd

我正在编写 .Rmd 文档,向人们展示如何使用命令行。这包括基于 bash 的代码块,如下所示:

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

但是,我们想对其进行参数化,所以有类似的东西

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

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

然而,这不起作用,因为在 bash 代码块中,参数不存在。 有没有办法在这种情况下使用参数,本质上是评估 params$testparam before knitr 认为它在非 R 代码块中?

理想情况下,解决方案将使以下成为可能:

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

变成

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

以下.Rmd可以够吗?我在 R 块中使用 system()

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

来自here.的强烈灵感 当然,bash 命令并不容易看到,但我怀疑可以解决这个问题。

编辑:

只需一点 work-around/hack,您就可以按以下方式呈现 bash 代码:

```{r bashCode, results="asis", echo=FALSE}
bash_code <- sprintf("echo '%s'", params$testparam)
cat("<pre class='bash'><code>",
    bash_code,
    "</code></pre>")
```

```{r bashOutput, echo=FALSE}
cat(system(bash_code, intern = TRUE), sep = "\n")
```

所以我们生成 bash 代码作为 charactercat bash 代码包装在适当的 html 中,同时告诉 knitr 来解释结果 'asis'(使结果显示为代码)。由于我们还抑制了 R 代码本身 (echo=FALSE),因此结果仅显示为代码。 接下来,在后续的块中,我们再次抑制代码的打印,但得到以标准方式解释的系统命令的输出。

您当然也可以将@r2evans 的技巧与此结合使用。

如我所愿,这个小技巧奏效了:

---
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</code></pre>
<pre><code>## this would echo something else</code></pre>

如果您传递非简单对象,这将失败。我没有测试 vectors/lists/frames,虽然我怀疑它们会失败......但是因为你在那个块中使用 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</code></pre>
<pre><code>## this would be one thing</code></pre>