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

时间:2016-02-19 18:26:35

标签: r markdown pandoc

我在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多个片段写出最后一个代码块。

1 个答案:

答案 0 :(得分: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中可能有更好的方法来写这个,你不需要占位符。也可以自定义最后返回代码块的方式,例如在每个代码块之前添加标题。