2015-01-07 22 views
5

Una delle funzionalità che mi piace moltissimo in Sweave è l'opzione per avere \ SweaveInput {} di file Sweave separati per avere un rapporto più "modulare" e solo essere in grado di commentare parti del rapporto che non voglio essere generato con un singolo #\SweaveInput{part_x} piuttosto che dover commentare dentro o fuori interi blocchi di codice. Recentemente ho deciso di passare a R Markdown per diversi motivi, principalmente per praticità, l'opzione dell'integrazione interattiva (Shiny) nel report e il fatto che non ho davvero bisogno delle ampie opzioni di formattazione di LaTeX. Ho scoperto che tecnicamente pandoc è in grado di combinare più file Rmd in un output html semplicemente concatenandoli, ma sarebbe bello se questo comportamento potesse essere chiamato da un file Rmd "master".C'è un analogo di markdown R di SweaveInput {} per la generazione di report modulare?

Qualsiasi risposta sarebbe molto apprezzata anche se è solo "tornare a Sweave, non è possibile in Markdown".

Sto usando R 3.1.1 per Windows e Linux così come Rstudio 0.98.1056 e Rstudio server 0.98.983.

+1

Vorrei mettere questo come una risposta, ma io non uso \ SweaveInput quindi non sono sicuro se questo risponde. Ma questo link sembra utile: http: // yihui.nome/knitr/demo/child/ – Dason

+0

Grazie per l'input, la risposta di Dieter sotto mostra che questa è davvero la strada da percorrere. –

risposta

6

Usa qualcosa come questo nel documento principale:

```{r child="CapsuleRInit.Rmd"} 
``` 
```{r child="CapsuleTitle.Rmd", eval=TRUE} 
``` 
```{r child="CapsuleBaseline.Rmd", eval=TRUE} 
``` 

Usa eval=FALSE per saltare un bambino.

Per utenti RStudio: è possibile definire un documento principale per l'output in lattice, ma questo non funziona per i documenti RMD, quindi è sempre necessario passare al documento principale per l'elaborazione. Supporta la mia richiesta di funzionalità a RStudio; Ho provato già due volte, ma mi sembra che troppe poche persone utilizzino i documenti figli per metterli più in alto nell'elenco delle priorità.

+1

Come posso supportare la tua richiesta di funzionalità? –

+0

Non avrebbe più senso presentare la richiesta di funzionalità [qui] (https://github.com/yihui/knitr/issues)? – Dason

+0

Ne ho già presentato uno e ho supportato un'altra richiesta di qualcun altro. Non è una funzionalità di knitr, quindi il collegamento che Dason ha dato non è il posto giusto, ma piuttosto uno di RSTudio. –

1

Non capisco alcuni dei termini nella risposta sopra, ma la soluzione si riferisce alla definizione di una maglia personalizzata: gancio nell'intestazione YAML. Per i documenti multipartiti questo consente, ad esempio:

  • Avere un 'principale' o 'root' Rmarkdown file con un colpo di testa output: markdown_document YAML
  • rendere tutti i documenti figli da Rmd ⇒ md anticipo chiamando render, o non se questo è il tempo di limitazione
  • combinare più file (con l'opzione di codice bambino pezzo) in un unico (ad esempio per i capitoli in un report)
  • scrittura output: html_document (o altro formato) intestazioni YAML per questa uscita la compilazione al volo , prepending al contrassegno efficacemente scrivendo un nuovo file Rmarkdown
    • ... quindi rendere tale Rmarkdown per ottenere il risultato, eliminando file intermedi nel processo, se desiderato

Il codice per tutto quanto sopra (dumped here) è descritto here, un post che ho scritto dopo aver elaborato l'utilizzo degli hook di intestazione YAML personalizzati knit: recentemente (here).

La funzione personalizzata knit: (cioè la sostituzione rmarkdown::render) nell'esempio precedente è:

(function(inputFile, encoding) { 
    input.dir <- normalizePath(dirname(inputFile)) 
    rmarkdown::render(input = inputFile, encoding = encoding, quiet=TRUE, 
        output_file = paste0(input.dir,'/Workbook-tmp.Rmd')) 
    sink("Workbook-compiled.Rmd") 
    cat(readLines(headerConn <- file("Workbook-header.yaml")), sep="\n") 
    close(headerConn) 
    cat(readLines(rmdConn <- file("Workbook-tmp.Rmd")), sep="\n") 
    close(rmdConn) 
    sink() 

    rmarkdown::render(input = paste0(input.dir,'/Workbook-compiled.Rmd'), 
        encoding = encoding, output_file = paste0(input.dir,'/../Workbook.html')) 
    unlink(paste0(input.dir,'/Workbook-tmp.Rmd')) 
}) 

... ma tutto spremuto sulla linea 1!

Il resto del file 'master'/'root'/'control' o qualsiasi altra cosa si voglia chiamare, si occupa di scrivere il suddetto YAML per l'output HTML finale che passa attraverso un file Rmarkdown intermedio, e il suo secondo codice pezzo aggiunge programmazione documenti figli tramite una chiamata al list.files()

```{r include=FALSE} 
header.input.file <- "Workbook-header.yaml" 
header.input.dir <- normalizePath(dirname(header.input.file)) 
fileConn <- file(header.input.file) 
writeLines(c(
    "---", 
    paste0('title: "', rmarkdown::metadata$title,'"'), 
    "output:", 
    " html_document:", 
    " toc: true", 
    " toc_depth: 3 # defaults to 3 anyway, but just for ease of modification", 
    " number_sections: TRUE", 
    paste0(" css: ",paste0(header.input.dir,'/../resources/workbook_style.css')), 
    ' pandoc_args: ["--number-offset=1", "--atx-headers"]', 
    "---", sep="\n"), 
    fileConn) 
close(fileConn) 
``` 

```{r child = list.files(pattern = 'Notes-.*?\\.md')} 
# Use file names with strict numeric ordering, e.g. Notes-001-Feb1.md 
``` 

La struttura di directory contenente una cartella di livello superiore con

  1. un output finale Workbook.html
  2. Un resources sottocartella contenente workbook_style.css
  3. Un documents sottocartella contenente detto file principale "Workbook.Rmd" al fianco di file denominati come "Note-001.Rmd", "Note-002.Rmd", ecc (per garantire un fileglobbing su list.files(pattern = "Notes-.*?\\.Rmd) reperti e rende quindi quali bambini nell'ordine corretto durante il rendering il principale Workbook.Rmd del file)

Per ottenere una corretta numerazione dei file, ogni costituente "Note-XXX.Rmd" file deve contenere le seguenti stile YAM L intestazione:

--- 
title: "March: Doing x, y, and z" 
knit: (function(inputFile, encoding) { input.dir <- normalizePath(dirname(inputFile)); rmarkdown::render(input = inputFile, encoding = encoding, quiet=TRUE)}) 
output: 
    md_document: 
    variant: markdown_github 
    pandoc_args: "--atx-headers" 
--- 

```{r echo=FALSE, results='asis', comment=''} 
cat("##", rmarkdown::metadata$title) 
``` 

Il codice pezzo nella parte superiore del documento Rmarkdown entra nel titolo YAML come intestazione di secondo livello quando valutato. results='asis' indica per tornare normale stringa di testo piuttosto che

[1] "A text string" 

Si potrebbe maglia ciascuno di questi prima maglia il file principale - è più facile da eliminare l'obbligo di rendere tutti i documenti figli e basta aggiungere i loro prodotti in pre Markdown produzione.

Ho descritto tutto questo ai link sopra, ma ho pensato che sarebbe stato maleducato non lasciare il codice reale con la mia risposta.

Non so quanto sia efficace il sito Web di richiesta delle funzionalità di RStudio ... Personalmente non ho trovato difficoltà a consultare il codice sorgente per queste funzioni, che per fortuna sono open source e se c'è davvero qualcosa assente piuttosto che non documentato è probabile che una richiesta di funzionalità informata all'interno delle operazioni sia molto più utilizzabile da uno dei loro sviluppatori software.

Non ho familiarità con Sweave, il precedente era quello a cui miravi? Se ho capito bene, vuoi solo controllare l'inclusione dei documenti in modo modulare. La dichiarazione child = list.files() potrebbe occuparsi di questo: se non attraverso il globbing dei file, è possibile aggiornare i file di elenco come child = c("file1.md","file2md") ... e passare tale istruzione per cambiare i figli. È inoltre possibile controllare gli interruttori TRUE/FALSE con YAML, per cui la presenza di un header personalizzato fisserebbe alcuni bambini da includere per esempio

potentially.absent.variable: TRUE 

... sopra il documento con un silenzioso include=FALSE nasconde le macchinazioni del primo Chunk:

```{r include=FALSE} 
!all(!as.logical(rmarkdown::metadata$potentially.absent.variable) 
# ==> FALSE if potentially.absent.variable is absent 
# ==> FALSE if anything other than TRUE 
# ==> TRUE if TRUE 

checkFor <- function(var) { 
    return !all(!as.logical(rmarkdown::metadata[[var]]) 
} 
``` 

```{r child = "Optional_file.md", eval = checkFor(potentially.absent.variable)} 
```