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
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: 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")}}
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.
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 libraryrównież , czy pakiet został już załadowany). Oto uproszczona implementacja requireilustrująca to, co robi:
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.
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.
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.6765.1816.5969685.6556.1779456.0061e+05
lib 17.19219.88727.30290720.85222.490255665.8811e+05
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.
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ć), podczasrequire()
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 zError: object “bar” not found
(powiedzmy) linią 175.Odpowiedzi:
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źródło
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),require
jest używana wewnątrz funkcji, ponieważ wyświetla ostrzeżenie i kontynuuje działanie, jeśli pakiet nie zostanie znaleziony, podczas gdylibrary
zgłosi błąd.źródło
require
jest to, że powstrzymuje mnie od mówienia o pakietach jakolibraries
praktyce, która napędza R-cognoscenti po ścianie. Jestlibrary
to lokalizacja katalogu, w którym znajdują się pakiety.require
, chyba że sprawdzisz wartość zwracaną (w takim przypadku zwykle są lepsze alternatywy, nploadNamespace
.).Kolejną zaletą
require()
jest to, że domyślnie zwraca wartość logiczną.TRUE
jeśli paczki są załadowane,FALSE
jeśli nie są.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.źródło
Możesz użyć,
require()
jeśli chcesz zainstalować pakiety, jeśli i tylko w razie potrzeby, takie jak:W przypadku wielu pakietów możesz użyć
Pro wskazówki:
W przypadku użycia w skrypcie można uniknąć ekranu okna dialogowego, określając
repos
parametrinstall.packages()
, npMożna owinąć
require()
orazlibrary()
wsuppressPackageStartupMessages()
celu dobrze, komunikaty stłumić pakiet startowy, a także wykorzystywać parametryrequire(..., quietly=T, warn.conflicts=F)
, jeśli potrzeba, aby utrzymać spokój instaluje.źródło
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
require
kod 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}:Może to prowadzić do subtelnie błędnych wyników. Użycie
library
zamiastrequire
generuje 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,
require
faktycznie wywołujelibrary
wewnętrznie (jeśli pakiet nie został jeszcze dołączony - wrequire
ten sposób przeprowadza kontrolę nadmiarową, ponieważ sprawdzalibrary
również , czy pakiet został już załadowany). Oto uproszczona implementacjarequire
ilustrująca to, co robi:Doświadczeni programiści R zgadzają się:
Yihui Xie , autor {knitr}, {bookdown} i wielu innych pakietów mówi :
Hadley Wickham , autor bardziej popularnych pakietów R niż ktokolwiek inny, mówi
źródło
class::function
, użyj,library()
aby tego uniknąć.i zobaczysz:
źródło
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, arequire
jedynie 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.źródło
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.
źródło
library
zamiast tego naprawić implementację (obie funkcje, jak obecnie dostarczane z R, są ogromnym bałaganem).loadNamespace
, który ładuje pakiet i zwraca jego przestrzeń nazw, bez dołączania go.