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