Jaka jest różnica między wymaganiem () a biblioteką ()?

565

Jaka jest różnica między require()i library()?

Marco
źródło
7
Dodanie linku do posta na blogu @ Yihui, chyba że chce on opublikować jego wersję jako odpowiedź. yihui.name/en/2014/07/library-vs-require
MichaelChirico
4
Podsumowując wpis na blogu @ Yihui: „Panie i panowie! Powiedziałem to wcześniej: wymagany () jest niewłaściwym sposobem na załadowanie pakietu R; zamiast tego należy użyć biblioteki ()”
De Novo
1
@ DanHall ... ponieważ library()natychmiast zawiesza się głośno, wcześnie iz odpowiednim komunikatem o błędzie (jeśli pakiet nie jest zainstalowany lub nie można go załadować), podczas require()gdy nie zgłasza błędu, po prostu cicho zwraca wartość logiczną FAŁSZ, która zostaje wyrzucona, i powoduje awarię kodu później i bardziej tajemniczo z Error: object “bar” not found(powiedzmy) linią 175.
smci
1
@KonradRudolph: Gotowe! Dziękujemy za twoją opinię.
Marco,

Odpowiedzi:

85

Oprócz udzielonej już dobrej porady, dodałbym to:

Prawdopodobnie najlepiej unikać używania, require() chyba że faktycznie użyjesz wartości, którą zwraca, np. W pewnej pętli sprawdzania błędów, takiej jak podana przez thierry.

W większości innych przypadków lepiej jest użyć library(), ponieważ spowoduje to wyświetlenie komunikatu o błędzie podczas ładowania pakietu, jeśli pakiet nie jest dostępny. require()po prostu zawiedzie bez błędu, jeśli pakietu nie ma. To najlepszy czas, aby dowiedzieć się, czy pakiet musi zostać zainstalowany (a może nawet nie istnieje, ponieważ źle napisał). Otrzymywanie informacji zwrotnych o błędach wcześnie iw odpowiednim czasie pozwoli uniknąć potencjalnych problemów ze śledzeniem, dlaczego późniejszy kod zawiedzie, gdy próbuje użyć procedur bibliotecznych

dww
źródło
356

Nie ma go wiele w codziennej pracy.

Jednak zgodnie z dokumentacją dla obu funkcji (dostępną po wstawieniu ?przed nazwą funkcji i naciśnięciu klawisza Enter), requirejest używana wewnątrz funkcji, ponieważ wyświetla ostrzeżenie i kontynuuje działanie, jeśli pakiet nie zostanie znaleziony, podczas gdy libraryzgłosi błąd.

richiemorrisroe
źródło
1
#richiemorrisroe: Dziękuję. Czy to oznacza, że ​​jeśli załaduję pakiety, których potrzebuję na samym początku kodu R, nie ma znaczenia, który wybiorę?
Marco
6
tak długo, jak nie ładujesz pakietów wewnątrz funkcji, tak naprawdę nie ma to znaczenia. Ładuję wszystkie moje pakiety za pomocą wymagania i nie wiedziałem, jaka jest różnica, dopóki nie przeczytałem pomocy po zobaczeniu twojego pytania.
richiemorrisroe
45
Innym powodem, dla którego używam, requirejest to, że powstrzymuje mnie od mówienia o pakietach jako librariespraktyce, która napędza R-cognoscenti po ścianie. Jest libraryto lokalizacja katalogu, w którym znajdują się pakiety.
IRTFM
22
Mają bardzo istotne różnice. Nie używaj require, chyba że sprawdzisz wartość zwracaną (w takim przypadku zwykle są lepsze alternatywy, np loadNamespace.).
Konrad Rudolph,
256

Kolejną zaletą require()jest to, że domyślnie zwraca wartość logiczną. TRUEjeśli paczki są załadowane, FALSEjeśli nie są.

> 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

Możesz więc użyć require()w konstrukcjach takich jak ta poniżej. Przydaje się to przede wszystkim, jeśli chcesz rozpowszechniać swój kod w naszej instalacji R, ponieważ pakiety mogą nie zostać zainstalowane.

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")
    }
}
Thierry
źródło
65

Możesz użyć, require()jeśli chcesz zainstalować pakiety, jeśli i tylko w razie potrzeby, takie jak:

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

W przypadku wielu pakietów możesz użyć

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

Pro wskazówki:

  • W przypadku użycia w skrypcie można uniknąć ekranu okna dialogowego, określając reposparametr install.packages(), np

    install.packages(package, repos="http://cran.us.r-project.org")
  • Można owinąć require()oraz library()w suppressPackageStartupMessages()celu dobrze, komunikaty stłumić pakiet startowy, a także wykorzystywać parametry require(..., quietly=T, warn.conflicts=F), jeśli potrzeba, aby utrzymać spokój instaluje.

Daniel Sparing
źródło
46

Zawsze używaj library. Nigdy nie używaj 1require .

( 1 Prawie nigdy. Może .)

Krótko mówiąc, dzieje się tak dlatego, że podczas używania requirekod może dawać różne, błędne wyniki, bez sygnalizowania błędu . To rzadkie, ale nie hipotetyczne! Rozważ ten kod, który daje różne wyniki w zależności od tego, czy można załadować {dplyr}:

require(dplyr)

x = data.frame(y = seq(100))
y = 1
filter(x, y == 1)

Może to prowadzić do subtelnie błędnych wyników. Użycie libraryzamiast requiregeneruje tutaj błąd, wyraźnie sygnalizując, że coś jest nie tak. To jest dobre .

Utrudnia to także debugowanie wszystkich innych awarii: jeśli ty require na początku skryptu jest pakiet i używa się jego eksportu w wierszu 500, w wierszu 500 pojawi się komunikat o błędzie „nie znaleziono obiektu foo” błąd „nie ma pakietu o nazwie„ bla ””.

Jedyny dopuszczalny przypadek użycia require jest natychmiastowe sprawdzenie jego wartości zwracanej, jak pokazują niektóre inne odpowiedzi. Jest to dość powszechny wzorzec, ale nawet w tych przypadkach lepiej (i zalecane, patrz poniżej) zamiast oddzielić kontrolę istnienia i ładowanie pakietu.

Mówiąc bardziej technicznie, requirefaktycznie wywołuje librarywewnętrznie (jeśli pakiet nie został jeszcze dołączony - w requireten sposób przeprowadza kontrolę nadmiarową, ponieważ sprawdza library również , czy pakiet został już załadowany). Oto uproszczona implementacja requireilustrująca to, co robi:

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
}

Doświadczeni programiści R zgadzają się:

Yihui Xie , autor {knitr}, {bookdown} i wielu innych pakietów mówi :

Panie i panowie! Powiedziałem to wcześniej: wymagany () jest złym sposobem ładowania pakietu R. zamiast tego użyj biblioteki ()

Hadley Wickham , autor bardziej popularnych pakietów R niż ktokolwiek inny, mówi

Użyj library(x)w skryptach analizy danych. […] Nigdy nie musisz używać require()( requireNamespace()prawie zawsze jest lepszy)

Konrad Rudolph
źródło
Chciałem wskazać dokładnie to samo, chyba że wywołujesz WSZYSTKIE funkcje ze składnią class::function, użyj, library()aby tego uniknąć.
Ghost,
19
?library

i zobaczysz:

library(package)i require(package)oba ładują paczkę z nazwą packagei umieszczają ją na liście wyszukiwania. requirejest przeznaczony do użytku wewnątrz innych funkcji; zwraca FALSEi wyświetla ostrzeżenie (zamiast błędu jak library()ma to miejsce domyślnie), jeśli pakiet nie istnieje. Obie funkcje sprawdzają i aktualizują listę aktualnie załadowanych pakietów i nie ładują ponownie pakietu, który jest już załadowany. (Jeśli chcesz ponownie załadować taki pakiet, zadzwoń detach(unload = TRUE)lub unloadNamespacenajpierw.) Jeśli chcesz załadować pakiet bez umieszczania go na liście wyszukiwania, użyj requireNamespace.

dwstu
źródło
9

Moja początkowa teoria na temat różnicy była taka, że libraryładuje pakiety niezależnie od tego, czy są już załadowane, czy nie, tzn. Może ponownie załadować już załadowany pakiet, a requirejedynie sprawdza, czy jest załadowany, lub ładuje go, jeśli nie jest (a więc użycie funkcji które polegają na określonym pakiecie). Dokumentacja obala to jednak i wyraźnie stwierdza, że ​​żadna funkcja nie przeładuje już załadowanego pakietu.

dsb
źródło
18
to interesujące, ale tak naprawdę nie jest odpowiedzią na pytanie ...?
Ben Bolker
3

Wydaje się, że jest to różnica w już załadowanym pakiecie. Chociaż prawdą jest, że zarówno wymagania, jak i biblioteka nie ładują pakietu. Biblioteka wykonuje wiele innych czynności przed sprawdzeniem i zamknięciem.

I tak poleciłbym usunięcie „wymaga” od początku funkcji działającej 2 mil razy, ale jeśli z jakiegoś powodu musiałbym ją zachować. Wymagane jest technicznie szybsze sprawdzenie.

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
Kształt
źródło
Twierdzę, że jest to silny powód, aby libraryzamiast tego naprawić implementację (obie funkcje, jak obecnie dostarczane z R, są ogromnym bałaganem).
Konrad Rudolph
@KonradRudolph cóż, jeśli ktoś zamierza naprawić bibliotekę, może może również jawnie włączyć ładowanie według wersji i włączyć załącznik jako opcję argumentu
Shape
Tak, absolutnie się zgadzam, ale zmieniłyby one semantykę, a nie tylko wydajność. W każdym razie, wersja nigdy nie będzie działać z pakietami w R, niestety. Pracuję nad tym (naprawdę!). Jeśli chodzi o dołączanie, możesz użyć loadNamespace, który ładuje pakiet i zwraca jego przestrzeń nazw, bez dołączania go.
Konrad Rudolph