Hinzufügen eines Links zu @ Yihuis Blog-Beitrag, es sei denn, er möchte eine Version davon als Antwort veröffentlichen. yihui.name/de/2014/07/library-vs-require
MichaelChirico
4
Zusammenfassend @ Yihuis Blog-Beitrag: "Meine Damen und Herren, ich habe dies bereits gesagt: require () ist der falsche Weg, um ein R-Paket zu laden; verwenden Sie stattdessen library ()"
De Novo
1
@DanHall ... weil library()sofort laut, früh und mit einer relevanten Fehlermeldung ausfällt (wenn das Paket nicht installiert ist oder nicht geladen werden konnte), während require()kein Fehler ausgelöst wird, nur stillschweigend boolean FALSE zurückgegeben wird, das weggeworfen wird, und bewirkt, dass der Code später und kryptischer mit Error: object “bar” not found(sagen wir) Zeile 175
fehlschlägt.
1
@KonradRudolph: Fertig! Vielen Dank für dein Feedback.
Marco
Antworten:
86
Zusätzlich zu den bereits gegebenen guten Ratschlägen möchte ich Folgendes hinzufügen:
Es ist wahrscheinlich am besten, die Verwendung zu vermeiden, es require()sei denn, Sie verwenden tatsächlich den zurückgegebenen Wert, z. B. in einer Fehlerprüfschleife, wie sie von thierry angegeben wird.
In den meisten anderen Fällen ist die Verwendung besser library(), da beim Laden des Pakets eine Fehlermeldung angezeigt wird, wenn das Paket nicht verfügbar ist. require()wird nur ohne Fehler fehlschlagen, wenn das Paket nicht da ist. Dies ist der beste Zeitpunkt, um herauszufinden, ob das Paket installiert werden muss (oder möglicherweise gar nicht existiert, weil es falsch geschrieben wurde). Wenn Sie frühzeitig und zum relevanten Zeitpunkt eine Fehlerrückmeldung erhalten, vermeiden Sie mögliche Kopfschmerzen, wenn Sie feststellen, warum späterer Code fehlschlägt, wenn versucht wird, Bibliotheksroutinen zu verwenden
In der täglichen Arbeit gibt es nicht viel von einem.
Gemäß der Dokumentation für beide Funktionen (Zugriff durch Setzen eines ?vor dem Funktionsnamen und Drücken der Eingabetaste) requirewird jedoch innerhalb von Funktionen verwendet, da eine Warnung ausgegeben wird und fortgesetzt wird, wenn das Paket nicht gefunden wird, während libraryein Fehler ausgegeben wird.
#richiemorrisroe: Danke. Bedeutet das, dass es egal ist, welches ich wähle, wenn ich die Pakete lade, die ich ganz am Anfang meines R-Codes benötige?
Marco
6
Solange Sie keine Pakete in eine Funktion laden, macht dies keinen Unterschied. Ich lade alle meine Pakete mit require und wusste nicht, was der Unterschied ist, bis ich die Hilfe gelesen habe, nachdem ich Ihre Frage gesehen habe.
Richiemorrisroe
45
Der andere Grund, den ich benutze, requireist, dass ich mich nicht auf Pakete beziehe libraries, eine Praxis, die die R-Cognoscenti an die Wand treibt. Dies libraryist das Verzeichnis, in dem sich die Pakete befinden.
IRTFM
22
Sie haben sehr relevante Unterschiede. Nicht verwenden require, es sei denn, Sie überprüfen den Rückgabewert (und in diesem Fall gibt es normalerweise bessere Alternativen, z loadNamespace. B. ).
Konrad Rudolph
256
Ein weiterer Vorteil require()ist, dass standardmäßig ein logischer Wert zurückgegeben wird. TRUEWenn die Pakete geladen sind, FALSEist dies nicht der Fall .
> test <- library("abc")
Error in library("abc"): there is no package called 'abc'> test
Error: object 'test' not found> test <- require("abc")
Loading required package: abc
Warning message:
In library(package, lib.loc = lib.loc, character.only =TRUE, logical.return =TRUE,:
there is no package called 'abc'> test[1]FALSE
So können Sie require()in Konstruktionen wie der folgenden verwenden. Dies ist besonders praktisch, wenn Sie Ihren Code an unsere R-Installation verteilen möchten, wenn Pakete möglicherweise nicht installiert sind.
if(require("lme4")){
print("lme4 is loaded correctly")}else{
print("trying to install lme4")
install.packages("lme4")if(require(lme4)){
print("lme4 installed and loaded")}else{
stop("could not install lme4")}}
Sie können wickeln require()und library()in suppressPackageStartupMessages(), na ja, Unterdrückungs - Paket Startmeldungen und auch die Parameter verwenden , require(..., quietly=T, warn.conflicts=F)wenn nötig , um die Installationen ruhig zu halten.
Kurz gesagt, dies liegt daran, dass requireIhr Code bei der Verwendung möglicherweise andere, fehlerhafte Ergebnisse liefert, ohne einen Fehler zu signalisieren . Dies ist selten, aber nicht hypothetisch! Betrachten Sie diesen Code, der unterschiedliche Ergebnisse liefert, je nachdem, ob {dplyr} geladen werden kann:
require(dplyr)
x = data.frame(y = seq(100))
y =1
filter(x, y ==1)
Dies kann zu subtil falschen Ergebnissen führen. Die Verwendung von libraryanstelle von requirelöst hier einen Fehler aus und signalisiert deutlich, dass etwas nicht stimmt. Das ist gut .
Dies erschwert auch das Debuggen aller anderen Fehler: Wenn Sie requirezu Beginn Ihres Skripts ein Paket erstellen und dessen Exporte in Zeile 500 verwenden, wird in Zeile 500 die Fehlermeldung "Objekt 'foo' nicht gefunden" anstelle von " Fehler "Es gibt kein Paket namens 'bla'".
Der einzig akzeptable Anwendungsfall requireist, wenn der Rückgabewert sofort überprüft wird, wie einige der anderen Antworten zeigen. Dies ist ein ziemlich häufiges Muster, aber selbst in diesen Fällen ist es besser (und empfohlen, siehe unten), stattdessen die Existenzprüfung und das Laden des Pakets zu trennen.
Technisch gesehen werden requireAnrufe tatsächlich libraryintern aufgerufen (wenn das Paket noch nicht angehängt war - requireführt daher eine redundante Prüfung durch, da libraryauch geprüft wird, ob das Paket bereits geladen wurde). Hier ist eine vereinfachte Implementierung von, um requirezu veranschaulichen, was es tut:
Ich wollte genau das Gleiche zeigen, es sei denn, Sie rufen ALLE Funktionen mit der Syntax auf class::function, library()um genau das zu vermeiden.
Ghost
19
?library
und du wirst sehen:
library(package)und require(package)beide laden das Paket mit dem Namen
packageund setzen es in die Suchliste. requireist für die Verwendung in anderen Funktionen vorgesehen; Es wird zurückgegeben FALSEund gibt eine Warnung aus (anstelle eines Fehlers wie library()standardmäßig), wenn das Paket nicht vorhanden ist. Beide Funktionen überprüfen und aktualisieren die Liste der aktuell geladenen Pakete und laden ein bereits geladenes Paket nicht neu. (Wenn Sie ein solches Paket neu laden möchten, rufen Sie es an detach(unload = TRUE)oder
unloadNamespacezuerst.) Wenn Sie ein Paket laden möchten, ohne es in die Suchliste aufzunehmen, verwenden Sie requireNamespace.
Meine anfängliche Theorie über den Unterschied war, dass librarydie Pakete geladen werden, unabhängig davon, ob sie bereits geladen sind oder nicht, dh dass sie ein bereits geladenes Paket möglicherweise neu laden, während sie requirenur prüfen, ob es geladen ist, oder es laden, wenn dies nicht der Fall ist (daher die Verwendung in Funktionen) die auf ein bestimmtes Paket angewiesen sind). Die Dokumentation widerlegt dies jedoch und gibt ausdrücklich an, dass keine der beiden Funktionen ein bereits geladenes Paket neu lädt.
Hier scheint der Unterschied zu einem bereits geladenen Paket zu liegen. Es ist zwar richtig, dass sowohl require als auch library das Paket nicht laden. Die Bibliothek erledigt viele andere Dinge, bevor sie überprüft und beendet wird.
Ich würde empfehlen, "require" vom Anfang einer Funktion zu entfernen, die ohnehin 2 mil-mal ausgeführt wird, aber wenn ich sie aus irgendeinem Grund beibehalten muss. erfordern ist technisch eine schnellere Überprüfung.
microbenchmark(req = require(microbenchmark), lib = library(microbenchmark),times =100000)
Unit: microseconds
expr min lq mean median uq max neval
req 3.6765.1816.5969685.6556.1779456.0061e+05
lib 17.19219.88727.30290720.85222.490255665.8811e+05
Ich würde argumentieren, dass dies ein starker Grund ist, librarystattdessen die Implementierung zu korrigieren (beide Funktionen, wie sie derzeit mit R ausgeliefert werden, sind ein großes Durcheinander).
Konrad Rudolph
@KonradRudolph gut, wenn jemand Bibliothek reparieren will, kann er vielleicht auch das Laden nach Version explizit aktivieren und Anhang eine Argumentoption machen
Form
Ja, ich stimme absolut zu, aber diese würden die Semantik ändern, nicht nur die Leistung. Auf jeden Fall wird die Versionierung mit Paketen in R leider nie funktionieren. Ich arbeite an einem Ersatz dafür (wirklich!). Sie können loadNamespacedas Anhängen verwenden , das ein Paket lädt und seinen Namespace zurückgibt, ohne es anzuhängen.
library()
sofort laut, früh und mit einer relevanten Fehlermeldung ausfällt (wenn das Paket nicht installiert ist oder nicht geladen werden konnte), währendrequire()
kein Fehler ausgelöst wird, nur stillschweigend boolean FALSE zurückgegeben wird, das weggeworfen wird, und bewirkt, dass der Code später und kryptischer mitError: object “bar” not found
(sagen wir) Zeile 175Antworten:
Zusätzlich zu den bereits gegebenen guten Ratschlägen möchte ich Folgendes hinzufügen:
Es ist wahrscheinlich am besten, die Verwendung zu vermeiden, es
require()
sei denn, Sie verwenden tatsächlich den zurückgegebenen Wert, z. B. in einer Fehlerprüfschleife, wie sie von thierry angegeben wird.In den meisten anderen Fällen ist die Verwendung besser
library()
, da beim Laden des Pakets eine Fehlermeldung angezeigt wird, wenn das Paket nicht verfügbar ist.require()
wird nur ohne Fehler fehlschlagen, wenn das Paket nicht da ist. Dies ist der beste Zeitpunkt, um herauszufinden, ob das Paket installiert werden muss (oder möglicherweise gar nicht existiert, weil es falsch geschrieben wurde). Wenn Sie frühzeitig und zum relevanten Zeitpunkt eine Fehlerrückmeldung erhalten, vermeiden Sie mögliche Kopfschmerzen, wenn Sie feststellen, warum späterer Code fehlschlägt, wenn versucht wird, Bibliotheksroutinen zu verwendenquelle
In der täglichen Arbeit gibt es nicht viel von einem.
Gemäß der Dokumentation für beide Funktionen (Zugriff durch Setzen eines
?
vor dem Funktionsnamen und Drücken der Eingabetaste)require
wird jedoch innerhalb von Funktionen verwendet, da eine Warnung ausgegeben wird und fortgesetzt wird, wenn das Paket nicht gefunden wird, währendlibrary
ein Fehler ausgegeben wird.quelle
require
ist, dass ich mich nicht auf Pakete beziehelibraries
, eine Praxis, die die R-Cognoscenti an die Wand treibt. Dieslibrary
ist das Verzeichnis, in dem sich die Pakete befinden.require
, es sei denn, Sie überprüfen den Rückgabewert (und in diesem Fall gibt es normalerweise bessere Alternativen, zloadNamespace
. B. ).Ein weiterer Vorteil
require()
ist, dass standardmäßig ein logischer Wert zurückgegeben wird.TRUE
Wenn die Pakete geladen sind,FALSE
ist dies nicht der Fall .So können Sie
require()
in Konstruktionen wie der folgenden verwenden. Dies ist besonders praktisch, wenn Sie Ihren Code an unsere R-Installation verteilen möchten, wenn Pakete möglicherweise nicht installiert sind.quelle
Sie können verwenden,
require()
wenn Sie Pakete genau dann installieren möchten, wenn:Für mehrere Pakete können Sie verwenden
Profi-Tipps:
Bei Verwendung innerhalb des Skripts können Sie einen Dialogbildschirm vermeiden, indem Sie den
repos
Parameter von angebeninstall.packages()
, zSie können wickeln
require()
undlibrary()
insuppressPackageStartupMessages()
, na ja, Unterdrückungs - Paket Startmeldungen und auch die Parameter verwenden ,require(..., quietly=T, warn.conflicts=F)
wenn nötig , um die Installationen ruhig zu halten.quelle
Immer benutzen
library
. Nie 1 Verwendungrequire
.( 1 Fast nie. Vielleicht .)
Kurz gesagt, dies liegt daran, dass
require
Ihr Code bei der Verwendung möglicherweise andere, fehlerhafte Ergebnisse liefert, ohne einen Fehler zu signalisieren . Dies ist selten, aber nicht hypothetisch! Betrachten Sie diesen Code, der unterschiedliche Ergebnisse liefert, je nachdem, ob {dplyr} geladen werden kann:Dies kann zu subtil falschen Ergebnissen führen. Die Verwendung von
library
anstelle vonrequire
löst hier einen Fehler aus und signalisiert deutlich, dass etwas nicht stimmt. Das ist gut .Dies erschwert auch das Debuggen aller anderen Fehler: Wenn Sie
require
zu Beginn Ihres Skripts ein Paket erstellen und dessen Exporte in Zeile 500 verwenden, wird in Zeile 500 die Fehlermeldung "Objekt 'foo' nicht gefunden" anstelle von " Fehler "Es gibt kein Paket namens 'bla'".Der einzig akzeptable Anwendungsfall
require
ist, wenn der Rückgabewert sofort überprüft wird, wie einige der anderen Antworten zeigen. Dies ist ein ziemlich häufiges Muster, aber selbst in diesen Fällen ist es besser (und empfohlen, siehe unten), stattdessen die Existenzprüfung und das Laden des Pakets zu trennen.Technisch gesehen werden
require
Anrufe tatsächlichlibrary
intern aufgerufen (wenn das Paket noch nicht angehängt war -require
führt daher eine redundante Prüfung durch, dalibrary
auch geprüft wird, ob das Paket bereits geladen wurde). Hier ist eine vereinfachte Implementierung von, umrequire
zu veranschaulichen, was es tut:Erfahrene R-Entwickler sind sich einig:
Yihui Xie , Autor von {knitr}, {bookdown} und vielen anderen Paketen, sagt :
Hadley Wickham , Autor beliebterer R-Pakete als jeder andere, sagt
quelle
class::function
,library()
um genau das zu vermeiden.und du wirst sehen:
quelle
Meine anfängliche Theorie über den Unterschied war, dass
library
die Pakete geladen werden, unabhängig davon, ob sie bereits geladen sind oder nicht, dh dass sie ein bereits geladenes Paket möglicherweise neu laden, während sierequire
nur prüfen, ob es geladen ist, oder es laden, wenn dies nicht der Fall ist (daher die Verwendung in Funktionen) die auf ein bestimmtes Paket angewiesen sind). Die Dokumentation widerlegt dies jedoch und gibt ausdrücklich an, dass keine der beiden Funktionen ein bereits geladenes Paket neu lädt.quelle
Hier scheint der Unterschied zu einem bereits geladenen Paket zu liegen. Es ist zwar richtig, dass sowohl require als auch library das Paket nicht laden. Die Bibliothek erledigt viele andere Dinge, bevor sie überprüft und beendet wird.
Ich würde empfehlen, "require" vom Anfang einer Funktion zu entfernen, die ohnehin 2 mil-mal ausgeführt wird, aber wenn ich sie aus irgendeinem Grund beibehalten muss. erfordern ist technisch eine schnellere Überprüfung.
quelle
library
stattdessen die Implementierung zu korrigieren (beide Funktionen, wie sie derzeit mit R ausgeliefert werden, sind ein großes Durcheinander).loadNamespace
das Anhängen verwenden , das ein Paket lädt und seinen Namespace zurückgibt, ohne es anzuhängen.