R Markdown - 打印文档中使用的所有代码片段的简明方法

问题描述 投票:4回答:2

我在R Markdown中写了一篇报告,其中我不想在报告的主体中打印任何我的R代码 - 我只是想显示图,计算我替换为内联文本的变量,有时候显示少量的原始R输出。因此,我写这样的东西:

In the following plot, we see that blah blah blah:
```{r snippetName, echo=F}
plot(df$x, df$y)
```

Now...

这一切都很好。但我还想在文档的最后提供R代码,以便任何人好奇地看看它是如何产生的。现在我必须手动编写这样的东西:

Here is snippet 1, and a description of what section of the report
this belongs to and how it's used:
```{r snippetName, eval=F}
```
Here is snippet 2:
```{r snippetTwoName, eval=F}
```
<!-- and so on for 20+ snippets -->

一旦有多个代码片段,这就变得相当繁琐且容易出错。有什么方法可以循环遍历片段并自动打印出来吗?我希望我可以这样做:

```{r snippetName, echo=F, comment="This is snippet 1:"}
# the code for this snippet
```

并以某种方式将以下结果替换为编织时指定点的文档:

This is snippet 1:
```{r snippetName, eval=F}
```

我想我可以编写一些后处理代码来扫描.Rmd文件,找到所有片段,并用正则表达式或其他东西拉出代码(我似乎记得有一些选项文件,你可以用来将命令注入pandoc过程?),但我希望可能有更简单的东西。

编辑:这绝对不是重复 - 如果你彻底阅读我的问题,最后一个代码块显示我正在完成链接问题的答案建议(语法略有不同,这可能是混乱的根源? )。我正在寻找一种方法,不必手动为文档中的所有20多个片段写出最后一个代码块。

r markdown pandoc
2个回答
2
投票

由于这对knitr来说非常困难,如果不是不可能,我们可以利用下一步,pandoc编译,以及pandoc使用过滤器操作内容的能力。因此,我们使用echo=TRUE编写一个普通的Rmd文档,并在调用它们时照常打印代码块。

然后,我们编写一个过滤器,找到语言R的每个代码块(这是代码块在pandoc中的编码方式),将其从文档中删除(替换它,此处为空段)并将其存储在列表中。然后,我们在文档的末尾添加所有代码块的列表。对于最后一步,问题是没有办法告诉python过滤器在文档的末尾添加内容(haskell中可能有一种方法,但我不知道)。因此,我们需要在Rmd文档的末尾添加一个占位符,以告诉过滤器此时添加R代码。在这里,我认为占位符将是CodeBlock,代码为lastchunk

这是过滤器,我们可以保存为postpone_chunks.py

#!/usr/bin/env python

from pandocfilters import toJSONFilter, Str, Para, CodeBlock

chunks = []


def postpone_chunks(key, value, format, meta):
    if key == 'CodeBlock':
        [[ident, classes, keyvals], code] = value
        if "r" in classes:
            chunks.append(CodeBlock([ident, classes, keyvals], code))
            return Para([Str("")])
        elif code == 'lastchunk':
            return chunks

if __name__ == "__main__":
    toJSONFilter(postpone_chunks)

现在,我们可以让knitr用pandoc_args执行它。请注意,我们需要记住在文档末尾添加占位符。

---
title: A test
output:
  html_document: 
    pandoc_args: ["--filter", "postpone_chunks.py"]
---

Here is a plot.

```{r}
plot(iris)
```

Here is a table.

```{r}
table(iris$Species)
```

And here are the code chunks used to make them:

    lastchunk

在haskell中可能有更好的方法来编写它,在那里你不需要占位符。也可以自定义最后返回代码块的方式,例如在每个代码块之前添加标题。


4
投票

这在knitr中是可行的,不需要使用pandoc。基于Yihui在https://github.com/yihui/knitr-examples/blob/master/073-code-appendix.Rnw发布的一个例子

在整个文档中设置echo=FALSEopts_chunk$set(echo = FALSE)

然后把这个块放在最后打印所有代码:

 ```{r show-code, ref.label=all_labels(), echo = TRUE, eval=FALSE}

 ```

这将打印所有块的代码。目前他们都出现在一个街区;我想知道如何放入块标签或其他标题......现在我用评论开始我的块(在任何情况下可能都不是一个坏主意)。

更新:要仅显示已评估的块,请使用:ref.label = all_labels(!exists('engine')) - 请参阅问题40919201

© www.soinside.com 2019 - 2024. All rights reserved.