2014-02-12 7 views
13

In meinem Datensatz habe ich 60 Gruppen, die ich analysieren möchte, in einen HTML-Bericht mit R Markdown einfügen. Da ich die gleiche Analyse auf jede Gruppe anwenden möchte, hoffe ich, dass es eine Möglichkeit gibt, die Codebausteine ​​/ Analyse dynamisch zu generieren.Dynamische R-Markierblöcke generieren

Einfach, ich möchte vermeiden, den Block 60 Mal zu replizieren.

Ich bin auf diese this Frage, die Kinder in knitr verwendet. Ich habe versucht, dies mit dem Iris-Datensatz zu replizieren. In meinem Beispiel wollte ich nur drei H4-Titel generieren, einen für jede Spezies.

Es ist erwähnenswert, dass ich nicht mit diesem Ansatz verheiratet bin, es scheint nur in Bezug zu stehen, was ich tun möchte.

Hier sind die Dateien, die ich verwendet:

parent.RMD Datei. Dies wäre mein "Master" -Bericht.

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')) 
} 

`` `

Und hier ist child.Rmd.

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

Eine alternative Lösung wäre meine 'pander' Pkg mit nur einem' brew'-Datei verwenden, die Schleifen unterstützen: http://rapporter.github.io/pander/#brew-to-pandoc. Siehe das Beispiel "Short-Code-Long-Report". – daroczig

+0

Awesome, ich werde einen Blick darauf werfen – Btibert3

Antwort

13

Versuchen 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')` 

Sie können auch eine Template-Datei wie 'child.rmd' und setzen diese in Ihrer for-Schleife erstellen, damit Sie müssen nicht eine komplizierte Analyse in Anführungszeichen:

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

haben dann Ihre 'template.rmd' sein:

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

Ok, das hat genau so funktioniert, wie ich es mir gewünscht hatte. Meine Frage. Warum ist 'r einfügen (stricken (text = out), collapse = '\ n')' erforderlich? Wenn ich kompiliere, strickt es vorher die Schleife? Ich möchte nur diesen Code umschließen. Vielen Dank! – Btibert3

+1

Was Sie in der 'for' -Schleife erstellen, ist ein Zeichenvektor, aber Sie wollen, dass er wie der Rest des Nicht-Code-Teils der Datei funktioniert, wobei Zeichen (' \ n') die verschiedenen Zeilen trennen Machen Sie das, indem Sie den Vektor auf '\ n' einklappen. –

+0

Dies erwies sich als äußerst nützlich für die Automatisierung von Ausgaben in 'flexdashboard'. Aber was ich gerne verstehen würde ist, warum es notwendig ist zu schreiben '' '' Paste (stricken ... \ '' vs nur '' 'stricken .. \' '(keine Paste). FYI, ich kollabiere all mein Text vor dem stricken stricken (stricken (einfügen (out_list, collapse = "\ n")) '. –

5

Mit @ Sams Lösung habe ich folgende generische Funktion gemacht. Angenommen, Sie haben in der Spalte einen Datenrahmen mit der Bezeichnung grfDf mit Diagrammgrafikobjekten. Das Folgende ist alles, was Sie brauchen, um alle Graphen in Rmd zu plotten: r require(DiagrammeR); renderHtmlWidgetList(grfDf$graph, render_graph). Siehe den Code für Vorbehalte.

``` 
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') 
} 
```