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

时间:2019-03-28 18:03:04

标签: r r-markdown knitr

我正在处理一个.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"</code></pre>
<pre><code>## this would echo something else</code></pre>

2 个答案:

答案 0 :(得分:2)

正如我希望的那样,这个小技巧可以工作:

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

如果传递非简单对象,这将失败。我还没有测试过向量/列表/帧,尽管我怀疑它们会严重失败...但是由于您在该块中使用了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>

答案 1 :(得分:1)

以下.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

来自here.的强大灵感 当然,bash命令并不容易看到,但是我怀疑有人可以解决该问题。

编辑:

通过一些变通方法/ 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")
```

enter image description here

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

您当然也可以同时使用@ r2evans的技巧。