Was ist der Unterschied zwischen require () und library ()?


565

Was ist der Unterschied zwischen require()und library()?



7
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


356

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.


1
#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")
    }
}

65

Sie können verwenden, require()wenn Sie Pakete genau dann installieren möchten, wenn:

if (!require(package, character.only=T, quietly=T)) {
    install.packages(package)
    library(package, character.only=T)
}

Für mehrere Pakete können Sie verwenden

for (package in c('<package1>', '<package2>')) {
    if (!require(package, character.only=T, quietly=T)) {
        install.packages(package)
        library(package, character.only=T)
    }
}

Profi-Tipps:

  • Bei Verwendung innerhalb des Skripts können Sie einen Dialogbildschirm vermeiden, indem Sie den reposParameter von angeben install.packages(), z

    install.packages(package, repos="http://cran.us.r-project.org")
  • 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.


46

Immer benutzen library. Nie 1 Verwendung require.

( 1 Fast nie. Vielleicht .)

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 library auch geprüft wird, ob das Paket bereits geladen wurde). Hier ist eine vereinfachte Implementierung von, um requirezu veranschaulichen, was es tut:

require = function (package) {
    already_attached = paste('package:', package) %in% search()
    if (already_attached) return(TRUE)
    maybe_error = try(library(package, character.only = TRUE)) 
    success = ! inherits(maybe_error, 'try-error')
    if (! success) cat("Failed")
    success
}

Erfahrene R-Entwickler sind sich einig:

Yihui Xie , Autor von {knitr}, {bookdown} und vielen anderen Paketen, sagt :

Meine Damen und Herren, ich habe dies bereits gesagt: require () ist der falsche Weg, um ein R-Paket zu laden; Verwenden Sie stattdessen library ()

Hadley Wickham , Autor beliebterer R-Pakete als jeder andere, sagt

Verwendung library(x)in Datenanalyseskripten. […] Sie müssen nie verwenden require()( requireNamespace()ist fast immer besser)


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.


9

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.


18
Das ist interessant, aber keine wirkliche Antwort auf die Frage ...?
Ben Bolker


3

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.676  5.181  6.596968  5.655  6.177   9456.006 1e+05
  lib 17.192 19.887 27.302907 20.852 22.490 255665.881 1e+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.
Konrad Rudolph
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.