2013-05-08 11 views
17

Kiedy bełkot/plączą dokument w celu wyodrębnienia kawałków R do skryptu, czy jest jakiś sposób, aby:knitr - wyklucza fragmenty z `purl (...)`?

  • wykluczyć dowolny fragment (według nazwy Say)?
  • jeśli nie, wyklucz porcję, jeśli eval=F (a może ja mogę zdefiniować porcję klocka/opcja include=F)?

Na przykład załóżmy, że mam następujące RMD:

```{r setup, echo=F} 
library(MASS) 
``` 
First, we perform the setup (assume for some reason I need to evaluate `setup` 
silently before I wish to display the chunk to the user, hence the repetition) 
```{r setup, eval=F} 
``` 

Here's the function I've been explaining: 
```{r function} 
plus <- function (a, b) a + b 
``` 

And here's an example of its use: 
```{r example} 
plus(1, 2) 
``` 

splątanych skrypt wygląda tak:

## @knitr setup, echo=F 
library(MASS) 

## @knitr setup, eval=F 
library(MASS) 

## @knitr function 
plus <- function (a, b) a + b 

## @knitr example 
plus(1, 2) 

Mam pomysł, że skoro ja nie zrobił” t chce, aby określone fragmenty zostały ocenione, one przynajmniej nie powinny pojawić się na wyjściu (w powyższym przykładzie, e sekunda setup porcja).

Dodatkowo byłoby mi miło zaznaczyć niektóre kawałki jako "niewidoczne" w odniesieniu do splątanego wyjścia. Nie chcę fragmentu example w moim wyjściowym skrypcie (było to miłe w Rmd dla celów dokumentacji, ale chcę mieć możliwość zaplątania Rmd, a potem tylko source('myfile.r'), jeśli chcę użyć funkcji plus, bez konieczności Obawiam się, że te dodatkowe przykłady są wykonywane.To obecnie plączę Rmd, a następnie ręcznie edytuję fragmenty, których nie chcę ze skryptu, co wydaje się sprzeczne z zasadą napisania jednego Rmd, który zapewni zarówno dokumentację, jak i skrypt bez dodatkowy wysiłek.)

+0

Uwaga - znakowanie kawałek z 'include = F' usunie go z' purl''d wyjścia, ale również * * od RMD (w wersji knitr z github, które jest; funkcja robi” t wydają się być obecne na moim komputerze w wersji 1.2), więc nie jest to idealne dla mojego bloku 'example' (gdzie chcę go * zawiera * w Rmd i usunięto go z pliku wyjściowego) –

+0

jest na pewno dużo miejsca na poprawa 'purl()', która jest rzadziej używana, a więc słabiej rozwinięta –

+0

Czy nie ma sposobu na wyodrębnienie r fragmentów z Rmd? – KLDavenport

Odpowiedz

20

Od knitr 1.3 istnieje nowa opcja porcji purl = TRUE/FALSE, która pozwala zawrzeć/wykluczyć niektóre fragmenty kodu dla purl().

```{r test, purl=FALSE} 
library(MASS) 
``` 
7

blok przetwarzania plątanina aktualnie nie poszerzyć params, ale możemy to zrobić ...

# See `?trace` documentation for details. 
bdy <- as.list(body(knitr:::process_tangle.block)) 
trace.at <- which(grepl(".*opts_chunk\\$merge.*", 
         as.list(body(knitr:::process_tangle.block)))) 
tracer <- quote({ 
    # Code borrowed from normal chunk procesing. 
    af = opts_knit$get('eval.after'); al = opts_knit$get('aliases') 
    if (!is.null(al) && !is.null(af)) af = c(af, names(al[af %in% al])) 
    for (o in setdiff(names(params), af)) params[o] = list(eval_lang(params[[o]])) 
    # Omit this if using lastest knitr source from github. 
    if(isFALSE(params$include)) { 
    tmp <- knit_code$get(); 
    tmp[[params$label]] <- ""; 
    knit_code$restore(tmp) 
    } 
}) 

trace(knitr:::process_tangle.block, tracer=tracer, at=trace.at, print=FALSE) 

Następnie bełkot() wykluczenie może być sterowany za pomocą argumentów opcji ...

```{r setup, echo=TRUE, results='hide'} 
library(MASS) 
```` 

First, we perform the setup (assume for some reason I need to evaluate `setup` 
silently before I wish to display the chunk to the user, hence the repetition) 
```{r setup2, ref.label="setup", echo=FALSE, results='markup'} 
``` 

Here's the function I've been explaining: 
```{r function} 
plus <- function (a, b) a + b 
``` 

And here's an example of its use: 
```{r example, eval=!opts_knit$get("tangle") } 
plus(1, 2) 
``` 

And here's another example of its use: 
```{r example2, include=!opts_knit$get("tangle") } 
plus(3, 3) 
``` 
+0

Jednak to nadal nie pozwala mi * wyłączyć * fragmentów które wybrałem (na przykład w przykładzie podanym w pytaniu, chcę wykluczyć fragment "przykładowy") –

+0

@ mathematical.coffee, patrz edit; powinien teraz działać dobrze. – Thell

+0

@ mathematical.coffee @ Thell dzięki za eksplorację; Myślę, że dodam oddzielną opcję porcji, aby umożliwić wyłączenie niektórych porcji z 'purl()'; pozwól, że pomyślę o tym więcej. –

3

Chociaż jest to raczej sztuczka niż rozwiązanie, nadal można zmodyfikować skrypt wynikającej z purl z niektórych wyrażeń regularnych.

na przykład za pomocą następującego wzoru (być może jest prostsze rozwiązanie wyrażenia regularnego)

dropchunks <- function(scriptname, what.to.drop){ 
    script <- readLines(scriptname) 
    script <- do.call(paste, list(script, collapse = "\n")) 
    subpattern = paste0("(", do.call(paste, list(what.to.drop, collapse="|")), ")") 
    mainpattern <- paste('(?s)## @knitr ((?!## @knitr).)*?', subpattern, '.*?((?=## @knitr)|$)', sep="") 
    script <- gsub(pattern = mainpattern, replacement = "", x = script, perl=TRUE) 
    writeLines(text = script, con= scriptname) 
} 

Następnie można to zrobić, aby usunąć cały kod fragment zawierający eval = F:

library(knitr) 
purl("test.Rmd") 
dropchunks("test.R", "eval=F") 

Możesz to zrobić, aby usunąć porcję o nazwie "function" lub "example" (a tak naprawdę usunie ona dowolną porcję zawierającą te słowa, ale można to zmienić, zmieniając wyrażenie):

purl("test.Rmd") 
dropchunks("test.R", c("function", "example")) 
+0

Podoba mi się ten pomysł! Ponieważ knitr nie narzeka na nieznane argumenty w kawałku, prosty "' 'r test, purl = F} może być ustawiony jako domyślny" what.to.drop ". – Thell