2014-10-21 11 views
5

Quando eseguo il rendering dei file di markdown Rmd che utilizzano blocchi in cache in RStudio utilizzando il pulsante Knit HTML, trovo che l'ordine in cui i pacchetti sono caricati non viene ricordato dal blocco a pezzo. Ciò causa problemi quando ho bisogno di caricare i pacchetti in un ordine specifico per evitare scontri nello spazio dei nomi.knitr chiamato da RStudio non conserva l'ordine in cui vengono caricati i pacchetti

Per un esempio riproducibile (che richiede i plyr, dplyr, e pacchetti pryr da installare, vedi sotto), I Iniziamo creando un documento Rmd knitr che carica plyr quindi dplyr (che sia esportare una funzione summarise), quindi utilizza pryr per determinare la funzione di riepilogo trovata. I maglia usando questo pulsante di RStudio "Knit HTML":

```{r} 
library(knitr) 
opts_chunk$set(cache = TRUE, message = FALSE) 
``` 

```{r test1} 
library(plyr) 
library(dplyr) 
``` 

```{r test2, dependson = "test1"} 
attr(pryr::where("summarise"), "name") 
``` 

Come raccomandato here, mi carico plyr prima dplyr in modo che funzioni di dplyr dovrebbero venire prima nel percorso di ricerca. Come previsto, il file di output md dimostra che la funzione summarise proviene da dplyr:

attr(pryr::where("summarise"), "name") 
## [1] "package:dplyr" 

Tuttavia, se faccio qualche piccola modifica nel test2 pezzo:

```{r test2, dependson = "test1"} 
attr(pryr::where("summarise"), "name") # this is a change 
``` 

che fa sì che sia ricompilato, ora carica i pacchetti nell'ordine sbagliato, e summarise si trova in plyr:

attr(pryr::where("summarise"), "name") # this is a change 
## [1] "package:plyr" 

Si noti che questo problema non si verifica se uno è in esecuzione knit dalla riga di comando R, ma solo perché mantiene i pacchetti plyr e dplyr caricati nell'ambiente (se riavvio R si verifica lo stesso problema).

Sono consapevole che posso fare riferimento alle funzioni come dplyr::summarise per evitare la ridondanza, ma questo è piuttosto ingombrante. Non caricare affatto plyr non è un'opzione in quanto diversi pacchetti lo aggiungono inavvertitamente allo spazio dei nomi. Come posso garantire che i pacchetti vengano caricati nell'ordine desiderato?

Sto usando l'ultima versione di RStudio (0.98.1079), e la mia sessionInfo è qui sotto:

## R version 3.1.1 (2014-07-10) 
## Platform: x86_64-apple-darwin13.1.0 (64-bit) 
## 
## locale: 
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 
## 
## attached base packages: 
## [1] stats  graphics grDevices utils  datasets methods base  
## 
## other attached packages: 
## [1] plyr_1.8.1 dplyr_0.3.0.2 knitr_1.7  
## 
## loaded via a namespace (and not attached): 
## [1] assertthat_0.1 codetools_0.2-8 DBI_0.3.0  digest_0.6.4  
## [5] evaluate_0.5.5 formatR_1.0  htmltools_0.2.4 magrittr_1.0.0 
## [9] parallel_3.1.1 pryr_0.1.0.9000 Rcpp_0.11.2  rmarkdown_0.3.10 
## [13] rstudioapi_0.1 stringr_0.6.2 tools_3.1.1 

Nota che, se necessario, è possibile impostare i pacchetti necessari per questo esempio riproducibile:

```{r} 
install.packages(c("devtools", "plyr", "dplyr")) 
devtools::install_github("hadley/pryr") 
``` 
+1

Ciò accade anche quando si utilizza 'cache = FALSE'? – Andrie

+0

@Andrie: No (e non me lo sarei aspettato), anche se la cache è necessaria per i miei scopi –

risposta

5

My pull request a knitr affronta questo problema mantenendo l'ordine del percorso di ricerca nel file __packages. Il codice di riferimento è:

x = rev(.packages()) 
if (file.exists(path)) 
    x = setdiff(c(readLines(path), x), .base.pkgs) 
writeLines(x, path) 

@Yihui fuse la richiesta come di this commit, e sarà probabilmente disponibile in knitr v1.8 a CRAN (o immediatamente da GitHub o RForge).

Ci possono ancora essere problemi quando i pacchetti vengono caricati in blocchi diversi che non dipendono l'uno dall'altro, ma questo risolve l'esempio nella domanda sopra e in altre applicazioni che ho provato.

3

Pubblicare questo come una risposta poiché sembra più sostanziale di un commento.

tl; dr: provare a rimuovere manualmente cache/__packages tra le esecuzioni (e l'aggiunta di cache=FALSE al vostro pacchetto di carico pezzo/fare senza pacchetto caching) e vedere se questo risolve il problema ... o anche aggiungere

if (file.exists("cache/__packages")) unlink("cache/__packages") 

(non ho in realtà testato questo sul tuo esempio.)

ho avuto un sacco di problemi con il pacchetto caching, soprattutto nelle directory in cui sto correndo un sacco di esempi di non-necessariamente lavorare set di pacchetti compatibili. Spesso rimuovo solo cache/__packages a mano.Immagino che il design possa essere migliorato (ma non mi sono preso la briga di costruire esempi/pensare a come il design sarebbe migliorato).

+2

I pacchetti di caricamento hanno effetti collaterali e gli effetti collaterali sono generalmente pericolosi per la memorizzazione nella cache. La soluzione semplice, come spiegato in http://yihui.name/knitr/demo/cache/, è _non_ per memorizzare blocchi di codice che hanno effetti collaterali. Se qualcuno sa come migliorare il design attuale o vuole lavorarci, non esitare a inviare richieste di pull. –

+2

@Yihui: Grazie- ho inviato [tale richiesta] (https://github.com/yihui/knitr/pull/867). Ho confermato che risolve il problema nel mio esempio riproducibile e, a meno che non ci sia un motivo specifico per la memorizzazione dei pacchetti in ordine alfabetico, non penso che possa causare problemi. –

+0

@DavidRobinson Molto apprezzato! Domani darò un'occhiata. –

Problemi correlati