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

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

 447
Author: David Arenburg, 2011-04-08

9 answers

W codziennej pracy nie ma zbyt wiele.

Jednakże, zgodnie z dokumentacją dla obu funkcji (Dostęp poprzez umieszczenie ? przed nazwą funkcji i naciśnięcie enter), require jest używana wewnątrz funkcji, ponieważ wyświetla ostrzeżenie i kontynuuje, jeśli pakiet nie zostanie znaleziony, podczas gdy {[2] } spowoduje błąd.

 290
Author: richiemorrisroe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-18 08:35:46

Kolejną zaletą require() jest to, że domyślnie Zwraca wartość logiczną. TRUE Jeśli Pakiety są załadowane, FALSE Jeśli nie.

> 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żna więc używać require() w konstrukcjach takich jak ta poniżej. Co jest szczególnie przydatne, jeśli chcesz rozpowszechniać swój kod do naszej instalacji r, Jeśli Pakiety mogą nie być 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")
    }
}
 224
Author: Thierry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-18 05:33:25

Możesz użyć require() Jeśli chcesz zainstalować pakiety wtedy i tylko wtedy, gdy jest to konieczne, na przykład:

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

Dla 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)
    }
}

Porady Pro:

  • W przypadku użycia wewnątrz skryptu, można uniknąć ekranu dialogowego, podając parametr repos z install.packages(), na przykład

    install.packages(package, repos="http://cran.us.r-project.org")
    
  • Możesz zawijać require() i library() w suppressPackageStartupMessages(), aby, cóż, tłumić komunikaty uruchamiania pakietu, a także użyć parametrów require(..., quietly=T, warn.conflicts=F), jeśli jest to konieczne, aby zachować instaluje cicho.

 54
Author: Daniel Sparing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-09 07:57:34

Oprócz dobrej rady już udzielonej, dodam jeszcze:

Prawdopodobnie najlepiej jest unikać używania require() chyba że będziesz używał zwracanej wartości np. w jakiejś pętli sprawdzania błędów, takiej jak podana przez thierry ' ego.

W większości innych przypadków lepiej jest użyć library(), ponieważ spowoduje to wyświetlenie komunikatu o błędzie w czasie ładowania pakietu, jeśli pakiet nie jest dostępny. require() po prostu zawiedzie bez błędu, jeśli pakiet nie istnieje. To najlepszy czas, aby znaleźć out, jeśli pakiet musi być zainstalowany (a może nawet nie istnieje, ponieważ jest źle napisany). Otrzymywanie informacji zwrotnych o błędach wcześnie i w odpowiednim czasie pozwoli uniknąć ewentualnych bólów głowy ze śledzeniem, dlaczego późniejszy kod nie powiedzie się, gdy spróbuje użyć procedur bibliotecznych

 44
Author: dww,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-06 22:50:40
?library

I zobaczysz:

library(package) i require(package) oba ładują pakiet z nazwą package i umieścić go na liście wyszukiwania. require jest przeznaczony do stosowania wewnątrz innych funkcji; zwraca FALSE i daje ostrzeżenie (raczej niż błąd library() robi domyślnie), jeśli pakiet nie istnieć. Obie funkcje sprawdzają i aktualizują listę aktualnie załadowanych pakiety i nie ładować ponownie pakietu, który jest już załadowany. (Jeśli chcesz przeładować taki pakiet, zadzwoń detach(unload = TRUE) lub unloadNamespace pierwszy.) Jeśli chcesz załadować paczkę bez umieszczania to na liście wyszukiwania, użyj requireNamespace.

 15
Author: dwstu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-03 21:11:09

Moja początkowa teoria na temat różnicy była taka, że library ładuje pakiety bez względu na to, czy są już załadowane, czy nie, tzn. może przeładować już załadowany pakiet, podczas gdy require sprawdza, czy są załadowane lub ładuje je, jeśli nie są (stąd użycie w funkcjach, które opierają się na określonym pakiecie). Dokumentacja odrzuca to jednak i wyraźnie stwierdza, że żadna z funkcji nie przeładuje już załadowanego pakietu.

 7
Author: dsb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-09 15:35:04

Zawsze używaj library. Nigdy1 użyj require.

(1 prawie nigdy. Może .)

W skrócie, dzieje się tak dlatego, że podczas używania require, twój kod może przynieść różne, błędne wyniki, bez sygnalizowania błędu. Jest to rzadkie, ale nie hipotetyczne! Rozważmy ten kod, który daje różne wyniki w zależności od tego, czy {dplyr} można załadować:

require(dplyr)

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

Może to prowadzić do subtelnie złych wyników. Using library zamiast require rzuca tutaj błąd, sygnalizując wyraźnie, że coś jest nie tak. To jest dobre.

Utrudnia również debugowanie wszystkich innych błędów: Jeśli require pakiet na początku skryptu i użyjesz jego eksportu w linii 500, otrzymasz komunikat o błędzie "object 'foo' not found" w linii 500, zamiast błędu "there is no package called 'bla'".

Jedynym dopuszczalnym przypadkiem użycia require jest natychmiastowe sprawdzenie jego wartości zwrotnej, ponieważ niektóre z Pozostałe odpowiedzi pokazują. Jest to dość powszechny wzorzec, ale nawet w tych przypadkach lepiej (i zalecane, patrz poniżej) oddzielić kontrolę istnienia i ładowanie pakietu.

Bardziej technicznie, require faktycznie wywołuje library wewnętrznie (jeśli pakiet nie był jeszcze dołączony - require w ten sposób wykonuje zbędne sprawdzenie, ponieważ library również sprawdza, czy pakiet był już załadowany). Oto uproszczona implementacja require, aby zilustrować, co to czy:

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, mówiłem już wcześniej: require () jest złym sposobem na załadowanie 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 potrzebujesz do użycia require() (requireNamespace() jest prawie zawsze lepiej)

 3
Author: Konrad Rudolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-10 11:14:54

Tutaj wygląda na różnicę na już załadowanym pakiecie. Chociaż prawdą jest, że zarówno require, jak i library nie ładują pakietu. Biblioteka robi wiele innych rzeczy przed sprawdzeniem i zakończeniem.

Zalecałbym usunięcie "require" z początku funkcji działającej 2mil razy, ale jeśli z jakiegoś powodu musiałem ją zachować. wymaganie to technicznie szybsza Kontrola.

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
 2
Author: Shape,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-12 15:41:08

require() ładuje wszystkie dodatkowe pakiety

 -8
Author: Qbik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-10 10:27:19