Résumant le billet de blog de @ Yihui: "Mesdames et messieurs, je l'ai déjà dit: require () est la mauvaise façon de charger un package R; utilisez plutôt library ()"
De Novo
1
@DanHall ... car library()échoue immédiatement bruyamment, tôt et avec un message d'erreur pertinent (si le package n'est pas installé ou n'a pas pu être chargé), alors que require()ne déclenche pas d'erreur, retourne simplement silencieusement booléen FALSE qui est jeté, et provoque l'échec du code plus tard et de manière plus cryptée avec la Error: object “bar” not foundligne 175 (par exemple).
smci
1
@KonradRudolph: Terminé! Merci pour votre avis.
Marco
Réponses:
87
En plus des bons conseils déjà donnés, j'ajouterais ceci:
Il est probablement préférable d'éviter d'utiliser à require()moins que vous n'utilisiez réellement la valeur qu'elle renvoie, par exemple dans une boucle de vérification d'erreur telle que donnée par Thierry.
Dans la plupart des autres cas, il est préférable de l'utiliser library(), car cela donnera un message d'erreur au moment du chargement du package si le package n'est pas disponible. require()échouera sans erreur si le paquet n'est pas là. C'est le meilleur moment pour savoir si le paquet doit être installé (ou n'existe peut-être même pas parce qu'il s'est mal orthographié). Obtenir un retour d'erreur tôt et au moment opportun évitera des maux de tête possibles en recherchant pourquoi le code échoue plus tard lorsqu'il tente d'utiliser des routines de bibliothèque
Il n'y en a pas beaucoup dans le travail quotidien.
Cependant, selon la documentation des deux fonctions (accessible en mettant un ?avant le nom de la fonction et en appuyant sur Entrée), il requireest utilisé à l'intérieur des fonctions, car il génère un avertissement et continue si le package n'est pas trouvé, alors libraryqu'il générera une erreur.
#richiemorrisroe: Merci. Cela signifie-t-il que si je charge les packages dont j'ai besoin au tout début de mon code R, peu importe celui que je choisis?
Marco
6
tant que vous ne chargez pas de packages dans une fonction, cela ne fait vraiment aucune différence. Je charge tous mes packages à l'aide de require et je ne savais pas quelle était la différence jusqu'à ce que je lise l'aide après avoir vu votre question.
richiemorrisroe
45
L'autre raison que j'utilise requireest que cela m'empêche de faire référence aux packages comme libraries, une pratique qui pousse le R-cognoscenti le long du mur. Le libraryest l'emplacement du répertoire où les paquets sont assis.
IRTFM
22
Ils ont des différences très pertinentes. Ne pas utiliser require, sauf si vous vérifiez la valeur de retour (et dans ce cas, il existe généralement de meilleures alternatives, par exemple loadNamespace).
Konrad Rudolph
256
Un autre avantage de require()est qu'il renvoie une valeur logique par défaut. TRUEsi les packages sont chargés, FALSEsinon.
> 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
Vous pouvez donc l'utiliser require()dans des constructions comme celle ci-dessous. Ce qui est surtout pratique si vous souhaitez distribuer votre code à notre installation R où les packages peuvent ne pas être installés.
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")}}
Vous pouvez envelopper require()et library()dans suppressPackageStartupMessages(), eh bien, les messages de paquet suppress, et également utiliser les paramètres require(..., quietly=T, warn.conflicts=F)si nécessaire pour maintenir le calme installations.
Utilisez toujours library. Jamais 1 utilisation require.
( 1 Presque jamais. Peut-être .)
En résumé, cela est dû au fait que, lors de l'utilisation require, votre code peut produire des résultats différents et erronés, sans signaler d'erreur . C'est rare mais pas hypothétique! Considérez ce code, qui donne des résultats différents selon que {dplyr} peut être chargé:
require(dplyr)
x = data.frame(y = seq(100))
y =1
filter(x, y ==1)
Cela peut conduire à des résultats subtilement faux. Utiliser libraryau lieu de requirerenvoie une erreur ici, signalant clairement que quelque chose ne va pas. C'est bien .
Cela rend également le débogage de tous les autres échecs plus difficile: si vous requireun package au début de votre script et utilisez ses exportations à la ligne 500, vous obtiendrez un message d'erreur «objet« foo »introuvable» à la ligne 500, plutôt qu'un erreur "il n'y a pas de package appelé 'bla'".
Le seul cas d'utilisation acceptable requireest lorsque sa valeur de retour est immédiatement vérifiée, comme le montrent certaines des autres réponses. Il s'agit d'un modèle assez courant, mais même dans ces cas, il est préférable (et recommandé, voir ci-dessous) de séparer le contrôle d'existence et le chargement du package.
Plus techniquement, requireappelle en fait en libraryinterne (si le package n'était pas déjà attaché - requireeffectue donc une vérification redondante, car vérifie libraryégalement si le package a déjà été chargé). Voici une implémentation simplifiée de requirepour illustrer ce qu'il fait:
Yihui Xie , auteur de {knitr}, {bookdown} et de nombreux autres packages dit :
Mesdames et messieurs, je l'ai déjà dit: require () est la mauvaise façon de charger un package R; utilisez plutôt library ()
Hadley Wickham , auteur de packages R plus populaires que quiconque, dit
Utilisation library(x)dans les scripts d'analyse de données. […] Vous n'avez jamais besoin d'utiliser require()( requireNamespace()c'est presque toujours mieux)
J'allais pointer exactement la même chose, sauf si vous appelez TOUTES les fonctions avec la syntaxe class::function, utilisez library()pour éviter précisément cela.
Ghost
19
?library
et vous allez voir:
library(package)et à la require(package)fois charger le package avec le nom
packageet le mettre sur la liste de recherche. requireest conçu pour être utilisé à l'intérieur d'autres fonctions; il retourne FALSEet donne un avertissement (plutôt qu'une erreur comme c'est le library()cas par défaut) si le package n'existe pas. Les deux fonctions vérifient et mettent à jour la liste des packages actuellement chargés et ne rechargent pas un package déjà chargé. (Si vous souhaitez recharger un tel package, appelez detach(unload = TRUE)ou d'
unloadNamespaceabord.) Si vous souhaitez charger un package sans le mettre dans la liste de recherche, utilisez requireNamespace.
Ma théorie initiale sur la différence était que librarycharge les packages qu'il soit déjà chargé ou non, c'est-à-dire qu'il peut recharger un package déjà chargé, tout en requirevérifiant simplement qu'il est chargé, ou le charge s'il ne l'est pas (donc l'utilisation dans les fonctions qui reposent sur un certain paquet). Cependant, la documentation réfute cela et déclare explicitement qu'aucune fonction ne rechargera un package déjà chargé.
Voici la différence sur un paquet déjà chargé. Bien qu'il soit vrai que require et library ne chargent pas le package. La bibliothèque fait beaucoup d'autres choses avant de vérifier et de quitter.
Je recommanderais de supprimer "require" depuis le début d'une fonction exécutée 2mil fois de toute façon, mais si, pour une raison quelconque, je devais la garder. exiger est techniquement une vérification plus rapide.
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
Je dirais que c'est une bonne raison de corriger l'implémentation à la libraryplace (les deux fonctions, telles qu'elles sont actuellement livrées avec R, sont un énorme gâchis).
Konrad Rudolph
@KonradRudolph eh bien, si quelqu'un va réparer la bibliothèque, il peut peut-être aussi activer explicitement le chargement par version et faire de l'attachement une option d'argument
Forme
Oui, je suis absolument d'accord, mais cela changerait la sémantique, pas seulement la performance. Quoi qu'il en soit, le versioning ne fonctionnera jamais avec les packages dans R, malheureusement. Je travaille sur un remplacement pour cela (vraiment!). Quant à l'attachement, vous pouvez utiliser loadNamespace, qui charge un package et retourne son espace de noms, sans l'attacher.
library()
échoue immédiatement bruyamment, tôt et avec un message d'erreur pertinent (si le package n'est pas installé ou n'a pas pu être chargé), alors querequire()
ne déclenche pas d'erreur, retourne simplement silencieusement booléen FALSE qui est jeté, et provoque l'échec du code plus tard et de manière plus cryptée avec laError: object “bar” not found
ligne 175 (par exemple).Réponses:
En plus des bons conseils déjà donnés, j'ajouterais ceci:
Il est probablement préférable d'éviter d'utiliser à
require()
moins que vous n'utilisiez réellement la valeur qu'elle renvoie, par exemple dans une boucle de vérification d'erreur telle que donnée par Thierry.Dans la plupart des autres cas, il est préférable de l'utiliser
library()
, car cela donnera un message d'erreur au moment du chargement du package si le package n'est pas disponible.require()
échouera sans erreur si le paquet n'est pas là. C'est le meilleur moment pour savoir si le paquet doit être installé (ou n'existe peut-être même pas parce qu'il s'est mal orthographié). Obtenir un retour d'erreur tôt et au moment opportun évitera des maux de tête possibles en recherchant pourquoi le code échoue plus tard lorsqu'il tente d'utiliser des routines de bibliothèquela source
Il n'y en a pas beaucoup dans le travail quotidien.
Cependant, selon la documentation des deux fonctions (accessible en mettant un
?
avant le nom de la fonction et en appuyant sur Entrée), ilrequire
est utilisé à l'intérieur des fonctions, car il génère un avertissement et continue si le package n'est pas trouvé, alorslibrary
qu'il générera une erreur.la source
require
est que cela m'empêche de faire référence aux packages commelibraries
, une pratique qui pousse le R-cognoscenti le long du mur. Lelibrary
est l'emplacement du répertoire où les paquets sont assis.require
, sauf si vous vérifiez la valeur de retour (et dans ce cas, il existe généralement de meilleures alternatives, par exempleloadNamespace
).Un autre avantage de
require()
est qu'il renvoie une valeur logique par défaut.TRUE
si les packages sont chargés,FALSE
sinon.Vous pouvez donc l'utiliser
require()
dans des constructions comme celle ci-dessous. Ce qui est surtout pratique si vous souhaitez distribuer votre code à notre installation R où les packages peuvent ne pas être installés.la source
Vous pouvez utiliser
require()
si vous souhaitez installer des packages si et seulement si nécessaire, tels que:Pour plusieurs packages, vous pouvez utiliser
Conseils de pro:
Lorsqu'il est utilisé dans le script, vous pouvez éviter un écran de dialogue en spécifiant le
repos
paramètre deinstall.packages()
, tel queVous pouvez envelopper
require()
etlibrary()
danssuppressPackageStartupMessages()
, eh bien, les messages de paquet suppress, et également utiliser les paramètresrequire(..., quietly=T, warn.conflicts=F)
si nécessaire pour maintenir le calme installations.la source
Utilisez toujours
library
. Jamais 1 utilisationrequire
.( 1 Presque jamais. Peut-être .)
En résumé, cela est dû au fait que, lors de l'utilisation
require
, votre code peut produire des résultats différents et erronés, sans signaler d'erreur . C'est rare mais pas hypothétique! Considérez ce code, qui donne des résultats différents selon que {dplyr} peut être chargé:Cela peut conduire à des résultats subtilement faux. Utiliser
library
au lieu derequire
renvoie une erreur ici, signalant clairement que quelque chose ne va pas. C'est bien .Cela rend également le débogage de tous les autres échecs plus difficile: si vous
require
un package au début de votre script et utilisez ses exportations à la ligne 500, vous obtiendrez un message d'erreur «objet« foo »introuvable» à la ligne 500, plutôt qu'un erreur "il n'y a pas de package appelé 'bla'".Le seul cas d'utilisation acceptable
require
est lorsque sa valeur de retour est immédiatement vérifiée, comme le montrent certaines des autres réponses. Il s'agit d'un modèle assez courant, mais même dans ces cas, il est préférable (et recommandé, voir ci-dessous) de séparer le contrôle d'existence et le chargement du package.Plus techniquement,
require
appelle en fait enlibrary
interne (si le package n'était pas déjà attaché -require
effectue donc une vérification redondante, car vérifielibrary
également si le package a déjà été chargé). Voici une implémentation simplifiée derequire
pour illustrer ce qu'il fait:Les développeurs R expérimentés conviennent:
Yihui Xie , auteur de {knitr}, {bookdown} et de nombreux autres packages dit :
Hadley Wickham , auteur de packages R plus populaires que quiconque, dit
la source
class::function
, utilisezlibrary()
pour éviter précisément cela.et vous allez voir:
la source
Ma théorie initiale sur la différence était que
library
charge les packages qu'il soit déjà chargé ou non, c'est-à-dire qu'il peut recharger un package déjà chargé, tout enrequire
vérifiant simplement qu'il est chargé, ou le charge s'il ne l'est pas (donc l'utilisation dans les fonctions qui reposent sur un certain paquet). Cependant, la documentation réfute cela et déclare explicitement qu'aucune fonction ne rechargera un package déjà chargé.la source
Voici la différence sur un paquet déjà chargé. Bien qu'il soit vrai que require et library ne chargent pas le package. La bibliothèque fait beaucoup d'autres choses avant de vérifier et de quitter.
Je recommanderais de supprimer "require" depuis le début d'une fonction exécutée 2mil fois de toute façon, mais si, pour une raison quelconque, je devais la garder. exiger est techniquement une vérification plus rapide.
la source
library
place (les deux fonctions, telles qu'elles sont actuellement livrées avec R, sont un énorme gâchis).loadNamespace
, qui charge un package et retourne son espace de noms, sans l'attacher.