【问题标题】:Create parametric R markdown documentation?创建参数 R 降价文档?
【发布时间】:2013-02-04 05:48:19
【问题描述】:

我想遍历我的 R markdown 文件中的结果集列表。当我生成输出时,我想在结果集的名称中包含一些文本,例如标题。

我发现的一个 hacky 解决方案是像这样直接在文档中硬编码 html 输出

## All results

```{r loopResults, echo=FALSE, results='asis'}
results = list(result1 = data.frame(x=rnorm(3), y=rnorm(3)), result2=data.frame(x=rnorm(3), y=rnorm(3)))

for(res in names(results)) {
  cat(paste("<h3>Results for: ", res, "</h3>>"))

  plot(results[[res]]$x, results[[res]]$y)
}

这似乎不是正确的做事方式,特别是因为我想通过 pandoc 创建 PDF 文档,并且必须更改硬编码的表达式。 (我目前有 h3(text, type) 等便利功能)。

有更好的方法吗?

【问题讨论】:

  • 由于您使用的是pandoc,您可能会发现包pander 很有用。特别是函数?pander::pandoc.header 可能很有趣。
  • 正确的方式。我相信这里真正的问题是你不应该使用&lt;h3&gt;;您应该使用降价语法### 代替 h3:en.wikipedia.org/wiki/Markdown#Headings
  • 我相信最干净的解决方案将取决于循环内的内容。如果循环中有很多代码,那么在Rmd 中实现所有内容将是最干净的。如果循环中有很多标记,那么使用brew 模板作为中间体将导致更简洁的解决方案。

标签: r markdown knitr pandoc


【解决方案1】:

我会结合使用brewknitr 来实现这一点。我会创建一个名为 doc.brew 的 brew 模板,看起来像这样

<% for (res in names(results)) { -%>

### Results for: <%= res %>

```{r}
plot(results[["<%= res %>"]]$x, results[["<%= res %>"]]$y)
```

<% } %>

您现在可以运行以下代码来获得所需的输出

results = list(
  result1 = data.frame(x=rnorm(3), y=rnorm(3)), 
  result2=data.frame(x=rnorm(3), y=rnorm(3))
)
brew::brew('doc.brew', 'doc.Rmd')
knit2html('doc.Rmd')

【讨论】:

  • 这个最符合我想做的。尽管示例代码很短,但我正在查看的应用程序会更长。太糟糕了,模板太冗长了,代码看起来很混乱。
【解决方案2】:

一种可能性是让您的降价文件生成降价而不是 HTML。例如:

## All results

```{r loopResults, echo=FALSE, results='asis'}
results = list(result1 = data.frame(x=rnorm(3), y=rnorm(3)), result2=data.frame(x=rnorm(3), y=rnorm(3)))

for(res in names(results)) {
  cat(paste("Results for: ", res,"\n"))
  cat("=========================\n")
  plot(results[[res]]$x, results[[res]]$y)
  cat("\n")
}
```

如果你在 R 中对它应用knit() 函数,你会得到如下的 Markdown 文件:

## All results

Results for:  result1 
=========================
![plot of chunk loopResults](figure/loopResults1.png) 
Results for:  result2 
=========================
![plot of chunk loopResults](figure/loopResults2.png) 

您应该能够使用pandoc 从这个文件生成 HTML 或 LaTeX 吗?

【讨论】:

    【解决方案3】:

    https://gist.github.com/yihui/3145751 之后,您可以编写一个包含的子模板并对其进行循环。

    foosub.Rmd

    Results for `r res`
    ---------------------------
    
    ```{r}
     plot(results[[res]]$x, results[[res]]$y)
    ```
    

    foo.Rmd

    ```{r loopResults, include=FALSE}
    results = list(result1 = data.frame(x=rnorm(3), y=rnorm(3)), result2=data.frame(x=rnorm(3), y=rnorm(3)))
    out=NULL
    
    for(i in 1:length(results)) {
    res = names(results)[i]
    out = c(out, knit_child('foosub.Rmd', sprintf('foosub-%d.txt', i)))
    }
    ```
    
    `r paste(out, collapse = '\n')`
    

    主文件中的代码块本身不会产生任何输出,它只是呈现子文档,每个结果一个,并将其全部存储在 out 中(这就是它有 include=FALSE 的原因)。所有格式化的输出都收集在out 变量中,并在最后一行插入。

    这有点尴尬,但它确实鼓励模块化,但它似乎并不像能够做到的那么简单:

    ```{r}
    for(i in 1:10){
    ```
    
    Plot `r i`
    -----------
    
    ```{r}
    plot(1:i)
    }
    ```
    

    你不能。

    【讨论】:

      【解决方案4】:

      pander 的替代解决方案:

      <% for (res in names(results)) { %>
      ### Results for: <%= res %>
      
      <%=
      plot(results[[res]]$x, results[[res]]$y)
      %>
      <% } %>
      

      只需Pandoc.brew 一次运行即可完成您的工作:

      > Pandoc.brew('doc.brew')
      
      ### Results for: result1
      
      ![](/tmp/Rtmp4yQYfD/plots/568e18992923.png)
      
      ### Results for: result2
      
      ![](/tmp/Rtmp4yQYfD/plots/568e6008ed8f.png)
      

      或者生成 HTML/docx/等。一次运行:

      > Pandoc.brew('doc.brew', output = tempfile(), convert = 'html')
      > Pandoc.brew('doc.brew', output = tempfile(), convert = 'docx')
      

      【讨论】:

        猜你喜欢
        • 2022-11-24
        • 1970-01-01
        • 2016-06-05
        • 1970-01-01
        • 2020-04-28
        • 1970-01-01
        • 2021-06-07
        • 2019-03-25
        • 1970-01-01
        相关资源
        最近更新 更多