在 for 循环中生成 markdown 注释
Posted
技术标签:
【中文标题】在 for 循环中生成 markdown 注释【英文标题】:generate markdown comments within for loop 【发布时间】:2013-06-15 06:07:26 【问题描述】:我正在尝试使用 knitr 基于具有 for 循环的 R 脚本生成 html 报告。我想从 for 循环中的 cmets 生成 markdown cmets,但我不确定是否可能。
这是一个简单的例子,这是在 test.R:
for (i in 1:5)
## This is a heading for `i`
#' This is a comment for `i`
print(i)
然后我使用 spin 生成一个 Rmd 文件: 自旋('test.R')
但是,Rmd 文件如下所示。
```r
for (i in 1:5)
## This is a heading for `i`
#' This is a comment for `i`
print(i)
```
R 块中的 markdown cmets 不会编译成 HTML。有可能吗?
谢谢, 彼得
【问题讨论】:
听起来您想在转换为 Rmd 之前运行一些 R 代码,而据我了解,它旋转(随后是 knit)以相反的方式进行。我认为 brew 模板在这里可能会有所帮助。 我认为你的意思是 roxygen cmets 而不是 Markdown cmets。正如@baptiste 所提到的,brew
对于此类任务(从循环生成文本)更为复杂。
@Yihui,你是对的。 R 文件包含 roxygen cmets,我希望在我运行 spin 后将其转换为 Markdown cmets。
@baptiste,谢谢你的建议,我去看看 brew。
【参考方案1】:
我认为您可以使用代码块选项 results='asis' 在 knitr 中获得您想要的内容,您可以在 R 脚本中的“#+”之后指定要传递给 spin(但代码看起来不太“干净”比@daroczig 提出的有趣的 brew 解决方案):
#+ results='asis', echo = FALSE
for (i in 1:5)
cat("## This is a heading for ", i, "\n")
cat("<!-- This is a comment for ", i, "-->\n")
print(i)
如果这是 test.R 脚本并且您执行 spin("test.R"),则生成的 md 文件将如下所示:
## This is a heading for 1
<!-- This is a comment for 1 -->
[1] 1
## This is a heading for 2
<!-- This is a comment for 2 -->
[1] 2
## This is a heading for 3
<!-- This is a comment for 3 -->
[1] 3
## This is a heading for 4
<!-- This is a comment for 4 -->
[1] 4
## This is a heading for 5
<!-- This is a comment for 5 -->
[1] 5
【讨论】:
这允许我将 cmets 放入输出中,但 cmets 没有使用 Markdown 表示法进行格式化。 使用降价符号格式化的 cmets 是什么意思?您正在寻找的是 html cmets 吗?如果是,你可以用同样的方法,看我编辑的例子 (+1) 我需要在print(i)
之后添加一个额外的 cat('\n')
,以便将标题 2 到 5 呈现为标题。【参考方案2】:
how to create a loop that includes both a code chunk and text with knitr in R 提供了一个对我有用的解决方案。通过在每个循环结束时使用 Both results='asis'
和 \n
前面的两个空格。
示例:
没有两个空格:
```r, results='asis'
headers <- list("We","are","your","friends")
for (i in headers)
cat("\n##H ", i, " \n")
cat("comment",i)
输出(html):
如您所见,cmets 和标题混在一起
解决方案:
有两个空格:cat(" \n")
在循环的末尾
for (i in headers)
cat("\n##H ", i, "\n")
cat("comment",i)
cat(" \n")# <---------------------------------
注意:cat(" \n")
需要放在最后,即使你在循环中绘制或计算它也不起作用。
【讨论】:
【参考方案3】:我在pander 包中基于brew
独立于@Yihui (重新)实现了knitr
的一些功能,如果您不想运行brew
,可以帮助解决此类(和类似)问题在knit
ting 之前。快速演示:
> Pandoc.brew(text = "# Demonstrating a nice loop
+ <% for (i in 1:5) %>
+ ## This is a header for <%=i%>
+ #' This is a comment for <%=i%>
+ <% %>")
# Demonstrating a nice loop
## This is a header for _1_
#' This is a comment for _1_
## This is a header for _2_
#' This is a comment for _2_
## This is a header for _3_
#' This is a comment for _3_
## This is a header for _4_
#' This is a comment for _4_
## This is a header for _5_
#' This is a comment for _5_
请注意,您也可以将文件传递给Pandoc.brew
(无需使用带有实际问题的text
参数的这种麻烦的设置),并且您也可以使用<% ... %>
标签,例如条件(例如显示或不呈现报告的一部分)。最重要的是:<% ... %>
(未处理的 R 命令)和<%= ... %>
(结果由pander
处理)标签之间存在巨大差异。后者意味着所有返回的 R 对象都转换为 Pandoc 的 markdown,例如:
> Pandoc.brew(text = "# Demonstrating a conditional
+ <% for (i in 1:5) %>
+ ## This is a header for <%=i%>
+ <% if (i == 3) %>
+ Hey, that's **almost** <%=pi%>, that's between <%=3:4%>! Wanna fit a model to _celebrate_?
+ <%= lm(mpg ~ hp, mtcars) %>
+ <% %>")
# Demonstrating a conditional
## This is a header for _1_
## This is a header for _2_
## This is a header for _3_
Hey, that's **almost** _3.142_, that's between _3_ and _4_! Wanna fit a model to _celebrate_?
--------------------------------------------------------------
Estimate Std. Error t value Pr(>|t|)
----------------- ---------- ------------ --------- ----------
**hp** -0.06823 0.01012 -6.742 1.788e-07
**(Intercept)** 30.1 1.634 18.42 6.643e-18
--------------------------------------------------------------
Table: Fitting linear model: mpg ~ hp
## This is a header for _4_
## This is a header for _5_
【讨论】:
感谢您的建议。我希望避免在 R 代码中使用太多显式标记,但很高兴知道有一个变通方法。以上是关于在 for 循环中生成 markdown 注释的主要内容,如果未能解决你的问题,请参考以下文章
在带有pdf输出的r markdown中的for循环中包含多个空行