2014-02-12 92 views
13

在我的數據集中,我有60個組要使用R Markdown放入HTML報告中進行分析。因爲我想對每個組應用相同的分析,所以我希望有一種方法可以動態生成代碼塊/分析。生成動態R降價塊

簡單地說,我想避免複製塊60次。

我遇到了這個this問題,它使用knitr中的孩子。我試圖用虹膜數據集複製這個。在我的下面的例子中,我想要做的就是生成三個H4標題,每個物種一個。

值得注意的是,我沒有與這種方法結婚,它似乎與我期待的相關。

下面是我使用的文件:

parent.RMD文件。這將是我的「主」報告。

Automate Chunks of Analysis in R Markdown 
======================================================== 


```{r setup, echo=FALSE} 
library(knitr) 
``` 


```{r run-numeric-md, include=FALSE} 
out = NULL 
for (i in as.character(unique(iris$Species))) { 
    out = c(out, knit_child('child.Rmd')) 
} 

```

這裏是child.Rmd

#### Species = `r [i]` 
+0

另一種解決辦法是使用我的'pander' PKG與支持循環只有一個'brew'文件:http://rapporter.github.io/pander/#brew-to-pandoc。請參閱「短代碼長報告」示例。 – daroczig

+0

太棒了,我會看看 – Btibert3

回答

13

嘗試knit_expand()

Automate Chunks of Analysis in R Markdown 
======================================================== 

```{r setup, echo=FALSE} 
library(knitr) 
``` 

```{r run-numeric-md, include=FALSE} 
out = NULL 
for (i in as.character(unique(iris$Species))) { 
    out = c(out, knit_expand(text='#### Species = {{i}}')) 
} 
``` 

`r paste(knit(text = out), collapse = '\n')` 

你也可以創建一個模板文件中像'child.rmd',並把這個在您的for循環,這樣你就不必加上引號一個複雜的分析:

out = c(out, knit_expand('template.rmd')) 

然後讓你的'template.rmd'成爲:

#### Species = {{i}} 
+0

好吧,那正好符合我的要求。我的問題。爲什麼需要粘貼(編織(text = out),摺疊='\ n')?當我編譯時,它是否預先編織循環?我只想圍繞這段代碼包裹頭部。謝謝! – Btibert3

+1

你在'for'循環中創建的是一個字符向量,但是你希望它像文件中非代碼部分的其餘部分一樣使用字符返回('\ n')分隔不同的行,所以通過摺疊'\ n'上的向量來實現。 –

+0

事實證明,這對於'flexdashboard'中的輸出自動化非常有用。但我想知道的是,爲什麼有必要編寫''''粘貼(編織... \''和'''''編織... \''(不粘貼)。「 僅供參考,我摺疊所有我的文本在運行之前編織即'編織(粘貼(out_list,collapse =「\ n」))'。 –

5

以@sam的解決方案,我做了以下通用函數。假設您有一個名爲grfDf的數據框,並且在列中有DiagrammeR圖形對象。以下是您需要繪製Rmd中所有圖表的全部內容:r require(DiagrammeR); renderHtmlWidgetList(grfDf$graph, render_graph)。請參閱代碼以瞭解注意事項。

``` 
require(knitr) 

#' Render a list of htmlWidgets using various tricks 
#' 
#' @param widgetList A list of htmlWidget objects to be rendered 
#' @param renderFunction The function to render individual widgets. It can be either a name 
#' of the rendering function, e.g., "render_graph" in DiagrammeR, or the actual function to 
#' be passed to this call. 
#' @return The knitted string. This is to be included in the output by using `r renderHtmlWidgetList(...)`; 
#' @details This is a collection of various tricks. See the URL citations in the code. 
#' Note that this code does alliterate global variables starting with "renderHtmlWidgetList_". 
#' You may want to delete them using rm(list = ls(pattern="renderHtmlWidgetList_*")). 
#' @examples Inlcude the following in the Rmd directly 
#' `r require(DiagrammeR); renderHtmlWidgetList(grfDf$graph, render_graph)` 
#' 
#' @export 

renderHtmlWidgetList <- function(widgetList, renderFunction){ 
    # error checking 
    stopifnot(is.list(widgetList)) 
    # handles if the renderFunction is actually a function 
    # http://stackoverflow.com/questions/10520772/in-r-how-to-get-an-objects-name-after-it-is-sent-to-a-function 
    if(is.function(renderFunction)) { 
    # convert back to string, because we need to knit it later 
    renderFunction <- deparse(substitute(renderFunction)) 
    } 
    stopifnot(is.character(renderFunction) & length(renderFunction)==1) 
    stopifnot(exists(renderFunction, mode = "function")) 
    # inject global vars; make sure we have a unique global var name 
    gVarName<- paste0("renderHtmlWidgetList_", sample(1:10000, 1)) 
    while (exists(gVarName)) { 
    gVarName<- paste0("renderHtmlWidgetList_", sample(1:10000, 1)) 
    } 
    # assigning widgetList to a global temp var 
    # http://stackoverflow.com/questions/5510966/create-a-variable-name-with-paste-in-r 
    assign(gVarName, widgetList, envir = .GlobalEnv) 
    # solution from https://gist.github.com/ReportMort/9ccb544a337fd1778179 
    out <- NULL 
    knitPrefix <- "\n```{r results='asis', cache=FALSE, echo=FALSE}\n\n" 
    knitSuffix <- "\n\n```" 
    for (i in 1:length(widgetList)) { 
    knit_expanded <- paste0(knitPrefix, renderFunction, "(", gVarName, "[[", i, "]])") 
    out = c(out, knit_expanded) 
    } 
    #invisible(out) 
    paste(knitr::knit(text = out), collapse = '\n') 
} 
```