2014-10-21 6 views
5

Wenn ich Rmd Markdown-Dateien, die im Cache zwischengespeicherte Stücke in RStudio mithilfe der Schaltfläche HTML stricken gerendert, finde ich, dass die Reihenfolge, in der Pakete geladen werden nicht aus Chunk erinnert zu klumpen. Dies führt zu Problemen, wenn ich Pakete in einer bestimmten Reihenfolge laden muss, um Namenskonflikte zu vermeiden.knitr aufgerufen von RStudio nicht die Reihenfolge, in der Pakete geladen werden

Für ein reproduzierbares Beispiel (die die Installation der Plyr-, Dplyr- und PRYR-Pakete erfordert, siehe unten), beginne ich mit der Erstellung eines Knitr-RMD-Dokuments, das plrr und dann dplrr lädt (die beide eine summarise-Funktion exportieren). verwendet dann pryr, um festzustellen, welche Zusammenfassungsfunktion gefunden wird. Ich stricke diese mit RStudio der „Knit HTML“ Knopf:

```{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") 
``` 

Wie empfohlen here, ich lade plyr vor dplyr so dass Funktionen des dplyr sollten zunächst im Suchpfad kommen. Wie erwartet, zeigt die Ausgabe md-Datei, dass die summarise Funktion von dplyr kommt:

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

jedoch, wenn ich mache eine kleine Änderung in den test2 Brocken:

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

, die sie verursacht sein neu kompiliert, lädt er jetzt die Pakete in der falschen Reihenfolge, und summarise in plyr gefunden:

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

Beachten Sie, dass dieses Problem nicht auftritt, wenn knit von der R-Befehlszeile ausgeführt wird, aber nur, weil es die Pakete plyr und dplyr in der Umgebung geladen hält (wenn ich R neu starte, tritt das gleiche Problem auf).

Ich bin mir bewusst, dass ich Funktionen wie dplyr::summarise beziehen kann, um Redundanz zu vermeiden, aber das ist ziemlich umständlich. Das Laden von plyr überhaupt ist keine Option, da mehrere Pakete versehentlich zum Namespace hinzugefügt werden. Wie kann ich sicherstellen, dass die Pakete in der gewünschten Reihenfolge geladen werden?

Ich verwende die neueste Version von RStudio (0.98.1079), und meine Session unter:

## 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 

Beachten Sie, dass, wenn nötig, können Sie mit den notwendigen Paketen für dieses reproduzierbare Beispiel ein:

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

Tritt dies auch auf, wenn Sie 'cache = FALSE' verwenden? – Andrie

+0

@Andrie: Nein (und ich hätte es nicht erwartet), obwohl Caching für meine Zwecke notwendig ist –

Antwort

5

My pull request zu Knitr behebt dieses Problem durch Beibehaltung der Reihenfolge des Suchpfads in der Datei __packages. Der entsprechende Code ist:

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

@Yihui fusionierte die Anfrage ab this commit, und es wird wahrscheinlich in knitr v1.8 in CRAN (oder unmittelbar von GitHub oder RForge) zur Verfügung steht.

Es kann immer noch Probleme geben, wenn Pakete in verschiedenen Blöcken geladen werden, die nicht voneinander abhängen, aber das behebt das Beispiel in der obigen Frage und in anderen Anwendungen, die ich ausprobiert habe.

3

Dies als eine Antwort zu veröffentlichen, da es substantieller scheint als ein Kommentar.

tl; dr: versuchen cache/__packages manuell zwischen den Läufen zu entfernen (und dem Hinzufügen von cache=FALSE zu Ihrem Paket-Lade chunk/ohne Paket-Caching zu tun) und sehen, ob dies das Problem löst ... oder sogar hinzufügen

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

(ich habe nicht wirklich getestet diese auf Ihrem Beispiel.)

ich habe mit Paket-Caching Ärger viel hatte, vor allem Verzeichnisse in der Arbeit, wo ich viele Beispiele mit nicht-notwendigerweise laufen kompatible Paketsätze. Ich entferne oft einfach von Hand.Ich stelle mir vor, dass das Design verbessert werden könnte (aber ich habe mir nicht die Mühe gemacht, Beispiele zu konstruieren/darüber nachzudenken, wie das Design verbessert werden würde).

+2

Das Laden von Paketen hat Nebenwirkungen, und Nebenwirkungen sind im Allgemeinen gefährlich für das Caching. Die einfache Lösung, wie unter http://yihui.name/knitr/demo/cache/ erklärt, ist _not_ zu Cache-Code-Chunks, die Nebenwirkungen haben. Wenn jemand weiß, wie er das aktuelle Design verbessern kann oder daran arbeiten möchte, können Sie Pull-Anfragen senden. –

+2

@Yihui: Danke- Ich habe [eine solche Anfrage] (https://github.com/yihui/knitr/pull/867) eingereicht. Ich habe bestätigt, dass es das Problem in meinem reproduzierbaren Beispiel löst, und wenn es keinen bestimmten Grund gibt, Pakete in alphabetischer Reihenfolge zu speichern, glaube ich nicht, dass es Probleme verursachen könnte. –

+0

@DavidRobinson Sehr geschätzt! Ich schaue später nach. –