在最终输出中显示一个R Markdown代码块

3

我正在使用Knitr、Markdown和Slidify撰写一份演示文稿。其中幻灯片将部分涉及Knitr作为主题,这也是我遇到问题的原因。例如,我不能在幻灯片上显示knitr-markdown块,因为它总是在第一次运行时被解释,即使我像这样做:

```
```{r eval = F, include = T}

```
``` 

如何防止代码块被解释并从最终输出中删除,以便在使用Markdown和Knitr时展示代码块的结构?

编辑:

我尝试了@Ramnath提供的版本,并制作了以下幻灯片:

## Testslide 1

```{r verbatimchunk, verbatim = TRUE}
x = 1 + 1
x
```

```{r regularchunk}
x = 1 + 1
x
```

---

## Testslide 2

```{r verbatimchunk_2, verbatim = TRUE}
x = 1 + 1
x
```

* element 1
* element 2

---

## Testslide 3

* element 1
* element 2


```{r verbatimchunk_3, verbatim = TRUE}
x = 1 + 1
x
```

第一和第二张幻灯片都没问题,但最后一张是有问题的。如果在演示文稿中verbatim代码块之前有一个项目列表,它会像平常一样被解释。所以这与 @Scott 的第一种解决方法相同。我不理解这个。
编辑2/3(可行解决方案)
```{r echo = FALSE}
require(knitr)
hook_source_def = knit_hooks$get('source')
knit_hooks$set(source = function(x, options){
  if (!is.null(options$verbatim) && options$verbatim){
    opts = gsub(",\\s*verbatim\\s*=\\s*TRUE\\s*", "", options$params.src)
    bef = sprintf('\n\n    ```{r %s}\n', opts, "\n")
    stringr::str_c(bef, paste(knitr:::indent_block(x, "    "), collapse = '\n'), "\n    ```\n")
  } else {
     hook_source_def(x, options)
  }
})
```

## Testslide

* Element one
* Element two


Some text here breaks list environment:

```{r verbatim = T}
any code
```

有疑问这是否可能。也许可以尝试使用 cat() 函数来引用所需的 knitr 代码,但我只能部分地实现,最后的 "```" 无法呈现。或者,您可以插入一个特定的符号集,例如 "/myknitrcode_start",然后在编织原始文档后查找并替换它为正确的代码。或者编写一个 R 函数来实现此功能。 - Maxim.K
3个回答

4
我认为您需要在```{r}后添加一个空字符串,这样knitr将不会执行该块,而是显示它。请参见此处的示例。
在幻灯片上,以下内容对我有效(其中顶部的内容被执行,底部的内容未被执行)。
---

```{r}
list(5, 6, 7)
```


    ```{r}`r ''`
    hist(rnorm(100))
    5 + 6
    ```

---

在幻灯片的第一个位置是什么意思? - sckott
1
要获取更多关于此的帮助,knitr谷歌小组可能是您最好的选择,尽管Yihui也在SO上。 - sckott
@cpfaff 我编辑了上面的答案。那个例子对我有效,其中顶部执行而底部不执行。 - sckott
好的,谢谢更新。是的,那么它比我想象的更脆弱。有时候可以工作,有时候不行。如果你在要展示的列表之前有一个列表,并希望将其文字显示出来,对我来说它实际上不起作用。而这实际上是我需要的确切内容。 - user1554736
1
“有时候可以工作,有时候不行”只是由于Markdown语法的问题:如果您在列表下缩进一个段落,则该段落将被视为列表的一部分;正如Ramnath所建议的那样,您必须使用<p></p>或其他方式终止列表。 - Yihui Xie
显示剩余2条评论

3

这里有另一种利用分块钩子的解决方案。思路是,如果您有一个选项为verbatim = TRUE的分块,则会激活该钩子并逐字输出分块内容。我已经确认它也与Slidify兼容。

```{r echo = FALSE}
require(knitr)
hook_source_def = knit_hooks$get('source')
knit_hooks$set(source = function(x, options){
  if (!is.null(options$verbatim) && options$verbatim){
    opts = gsub(",\\s*verbatim\\s*=\\s*TRUE\\s*", "", options$params.src)
    bef = sprintf('\n\n    ```{r %s}\n', opts, "\n")
    stringr::str_c(bef, paste(knitr:::indent_block(x, "    "), collapse = '\n'), "\n    ```\n")
  } else {
     hook_source_def(x, options)
  }
})
```

```{r verbatimchunk, verbatim = TRUE}
x = 1 + 1
x
```

```{r regularchunk}
x = 1 + 1
x
```

编辑:在列表后面放代码块的技巧在于需要打破列表环境。一个快速且不太优雅的方法就是添加一个空段落元素。或者,你可以修复钩子,使得空段落自动添加到代码块的开始位置。

* element 1
* element 2

<p></p>
```{r verbatimchunk_3, verbatim = TRUE}
x = 1 + 1
x
```

我在上面更新了我的帖子。你的解决方案和Scott建议的一样存在问题。 - user1554736
如果您查看Markdown,您会发现该块是使用块包装器输出的。我认为Markdown仍将其解释为列表的一部分,因为它尚未关闭。如果您在代码块之前添加任何文本,它将打破列表并显示您所寻求的输出。 - Ramnath
默认钩子可以通过 knit_hooks$get('source') 获取,我不喜欢从 knitr 复制其源代码,因为这可能会限制我在将来更新时的操作。更安全的做法是 hook_source <- knit_hooks$get('source'),然后在 knit_hooks$set(source = ...) 中使用 hook_source - Yihui Xie
我记得为什么我硬编码它。那时候,knitr的一个更新破坏了一些东西。但是你修复了它,所以现在你推荐的方法是更好的。我会更新我的答案。 - Ramnath

0

虽然来晚了,但这个方法似乎也可以:

```{r echo=FALSE, class.output="r", comment=""}
cat("```{r}\nx <- 1 + 1\nx\n```")
```

或者,等价但可能更易于阅读和编写:

```{r echo=FALSE, class.output="r", comment=""}
cat(paste(sep = "\n",
  "```{r}",
  "x <- 1 + 1",
  "x",
  "```"
))
```

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接