Qual è la differenza tra require () e library ()?


565

Qual è la differenza tra require()e library()?



7
Aggiungendo un link al post sul blog di @ Yihui a meno che non voglia pubblicare una versione di esso come risposta. yihui.name/en/2014/07/library-vs-require
MichaelChirico

4
Riassumendo il post del blog di Yihui: "Signore e signori, l'ho già detto prima: requis () è il modo sbagliato di caricare un pacchetto R; usate invece library ()"
De Novo

1
@DanHall ... perché library()fallisce immediatamente ad alta voce, in anticipo e con un messaggio di errore rilevante (se il pacchetto non è installato o non può essere caricato), mentre require()non genera un errore, restituisce silenziosamente FALSO booleano che viene gettato via, e fa sì che il codice fallisca più tardi e in modo più criptico con la Error: object “bar” not found(diciamo) linea 175.
smci,

1
@KonradRudolph: Fatto! Grazie per il tuo feedback.
Marco,

Risposte:


87

Oltre ai buoni consigli già forniti, aggiungerei questo:

Probabilmente è meglio evitare di usare a require() meno che tu non stia effettivamente usando il valore che restituisce, ad es. In qualche ciclo di controllo degli errori come quello dato da Thierry.

Nella maggior parte degli altri casi è meglio usarlo library(), perché questo darà un messaggio di errore al momento del caricamento del pacchetto se il pacchetto non è disponibile. require()fallirà senza errori se il pacchetto non è presente. Questo è il momento migliore per scoprire se il pacchetto deve essere installato (o forse non esiste nemmeno perché è stato scritto in modo errato). Ottenere feedback sugli errori in anticipo e al momento opportuno eviterà possibili mal di testa con il rilevamento verso il basso perché il codice successivo non riesce quando tenta di utilizzare le routine di libreria


356

Non ce n'è molto nel lavoro quotidiano.

Tuttavia, secondo la documentazione per entrambe le funzioni (cui si accede inserendo ?prima il nome della funzione e premendo invio), requireviene utilizzato all'interno delle funzioni, poiché emette un avviso e continua se il pacchetto non viene trovato, mentre libraryverrà generato un errore.


1
#richiemorrisroe: Grazie. Vuol dire che se carico i pacchetti di cui ho bisogno all'inizio del mio codice R, non importa quale scelgo?
Marco

6
fintanto che non si caricano pacchetti all'interno di una funzione, non fa davvero differenza. Carico tutti i miei pacchetti usando il comando request e non sapevo quale fosse la differenza finché non ho letto l'aiuto dopo aver visto la tua domanda.
richiemorrisroe,

45
L'altra ragione che uso requireè che mi impedisce di fare riferimento a pacchetti come libraries, una pratica che spinge l'R-cognoscenti sul muro. La libraryposizione della directory in cui si trovano i pacchetti.
IRTFM

22
Hanno differenze molto rilevanti. Non utilizzare require, a meno che non si controlli il valore di ritorno (e in tal caso in genere esistono alternative migliori, ad es loadNamespace.).
Konrad Rudolph,

256

Un altro vantaggio require()è che restituisce un valore logico per impostazione predefinita. TRUEse i pacchetti sono caricati, in FALSEcaso contrario.

> 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

Quindi puoi usare require()in costruzioni come quella qui sotto. Che è utile soprattutto se si desidera distribuire il codice alla nostra installazione R in cui i pacchetti potrebbero non essere installati.

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

È possibile utilizzare require()se si desidera installare pacchetti se e solo se necessario, come:

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

Per più pacchetti è possibile utilizzare

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

Suggerimenti professionali:

  • Se utilizzato all'interno dello script, è possibile evitare una schermata di dialogo specificando il reposparametro di install.packages(), ad esempio

    install.packages(package, repos="http://cran.us.r-project.org")
  • Si può avvolgere require()e library()in suppressPackageStartupMessages()a, bene, i messaggi del pacchetto sopprimere l'avvio, e anche utilizzare i parametri require(..., quietly=T, warn.conflicts=F), se necessario, per mantenere la quiete installazioni.


46

Usa sempre library. Mai 1 utilizzo require.

( 1 Quasi mai. Forse .)

In breve, ciò è dovuto al fatto che, durante l'utilizzo require, il codice potrebbe produrre risultati diversi, errati, senza segnalare un errore . Questo è raro ma non ipotetico! Considera questo codice, che produce risultati diversi a seconda che {dplyr} possa essere caricato:

require(dplyr)

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

Questo può portare a risultati leggermente sbagliati. Utilizzando libraryinvece di requiregenerare un errore qui, segnalando chiaramente che qualcosa non va. Questo è un bene .

Inoltre, rende più difficile il debug di tutti gli altri errori: se si crea requireun pacchetto all'inizio dello script e si utilizzano le sue esportazioni nella riga 500, nella riga 500 verrà visualizzato un messaggio di errore "oggetto" non trovato "nella riga 500 errore "non esiste un pacchetto chiamato 'bla'".

L'unico caso d'uso accettabile di requireè quando il suo valore di ritorno viene immediatamente verificato, come mostrano alcune delle altre risposte. Questo è un modello abbastanza comune ma anche in questi casi è meglio (e consigliato, vedi sotto) invece separare il controllo di esistenza e il caricamento del pacchetto.

Più tecnicamente, in requirerealtà chiama libraryinternamente (se il pacchetto non era già collegato, requirequindi esegue un controllo ridondante, perché controlla library anche se il pacchetto è già stato caricato). Ecco un'implementazione semplificata di requireper illustrare cosa fa:

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
}

Gli sviluppatori R esperti concordano:

Yihui Xie , autore di {knitr}, {bookdown} e molti altri pacchetti afferma :

Onorevoli colleghi, l'ho già detto prima: requisito () è il modo sbagliato di caricare un pacchetto R; utilizzare invece library ()

Hadley Wickham , autore di pacchetti R più popolari di chiunque altro, afferma

Utilizzare library(x)negli script di analisi dei dati. […] Non hai mai bisogno di usare require()( requireNamespace()è quasi sempre meglio)


Avrei puntato esattamente allo stesso modo, a meno che tu non stia chiamando TUTTE le funzioni con la sintassi class::function, usa library()per evitarlo esattamente.
Ghost

19
?library

e vedrai:

library(package)ed require(package)entrambi caricano il pacchetto con il nome packagee lo inseriscono nell'elenco di ricerca. requireè progettato per l'uso all'interno di altre funzioni; restituisce FALSEe fornisce un avviso (anziché un errore come library()per impostazione predefinita) se il pacchetto non esiste. Entrambe le funzioni controllano e aggiornano l'elenco dei pacchetti attualmente caricati e non ricaricano un pacchetto che è già caricato. (Se si desidera ricaricare un pacchetto del genere, chiamare detach(unload = TRUE)o unloadNamespaceprima.) Se si desidera caricare un pacchetto senza inserirlo nell'elenco di ricerca, utilizzare requireNamespace.


9

La mia teoria iniziale sulla differenza era che librarycarica i pacchetti indipendentemente dal fatto che sia già caricato o meno, cioè potrebbe ricaricare un pacchetto già caricato, mentre requirecontrolla solo che sia caricato o lo carica se non lo è (quindi l'uso nelle funzioni che si basano su un determinato pacchetto). La documentazione rifiuta ciò, tuttavia, e afferma esplicitamente che nessuna delle due funzioni ricaricherà un pacchetto già caricato.


18
questo è interessante, ma non è davvero una risposta alla domanda ...?
Ben Bolker,


3

Qui sembra esserci la differenza su un pacchetto già caricato. Mentre è vero che sia richiedono che la libreria non caricano il pacchetto. La libreria fa molte altre cose prima di controllare ed uscire.

Consiglierei di rimuovere "request" dall'inizio di una funzione in esecuzione 2mil volte comunque, ma se, per qualche motivo, avessi bisogno di mantenerlo. richiede è tecnicamente un controllo più veloce.

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

Direi che questo è un motivo valido per correggere l'implementazione library(entrambe le funzioni, come attualmente fornite con R, sono un gran casino).
Konrad Rudolph,

@KonradRudolph bene, se qualcuno risolverà la libreria, forse può anche abilitare il caricamento in base alla versione in modo esplicito e rendere l'allegato un'opzione argomento
Forma

Sì, sono assolutamente d'accordo, ma quelli cambieranno la semantica, non solo la performance. Comunque, sfortunatamente il controllo delle versioni non funzionerà mai con i pacchetti in R. Sto lavorando a un sostituto per questo (davvero!). Per quanto riguarda il collegamento, è possibile utilizzare loadNamespace, che carica un pacchetto e restituisce il suo spazio dei nomi, senza collegarlo.
Konrad Rudolph,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.