¿Cuál es la diferencia entre require() y library()?


¿Cuál es la diferencia entre require() y library()?

 447
Author: David Arenburg, 2011-04-08

9 answers

No hay mucho de uno en el trabajo diario.

Sin embargo, de acuerdo con la documentación de ambas funciones (a la que se accede poniendo un ? antes del nombre de la función y pulsando enter), require se usa dentro de funciones, ya que genera una advertencia y continúa si no se encuentra el paquete, mientras que library lanzará un error.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-18 08:35:46

Otro beneficio de require() es que devuelve un valor lógico por defecto. TRUE si el paquete está cargado, FALSE si no lo está.

> 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

Así que puedes usar require() en construcciones como la de abajo. Lo que es principalmente útil si desea distribuir su código a nuestra instalación de R, es posible que los paquetes no se instalen.

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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-18 05:33:25

Puede usar require() si desea instalar paquetes si y solo si es necesario, como:

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

Para múltiples paquetes puede usar

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

Consejos profesionales:

  • Cuando se usa dentro del script, puede evitar una pantalla de diálogo especificando el parámetro repos de install.packages(), como

    install.packages(package, repos="http://cran.us.r-project.org")
    
  • Puede envolver require() y library() en suppressPackageStartupMessages() para, bien, suprimir los mensajes de inicio del paquete, y también utilizar los parámetros require(..., quietly=T, warn.conflicts=F) si es necesario para mantener la se instala tranquilo.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-09 07:57:34

Además de los buenos consejos ya dados, yo añadiría esto:

Probablemente sea mejor evitar usar require() a menos que realmente esté usando el valor que devuelve, por ejemplo, en algún bucle de comprobación de errores como el dado por thierry.

En la mayoría de los otros casos es mejor usar library(), porque esto dará un mensaje de error en el momento de carga del paquete si el paquete no está disponible. require() fallará sin error si el paquete no está allí. Este es el mejor momento para encontrar fuera si el paquete necesita ser instalado (o tal vez ni siquiera existe porque se deletrea mal). Obtener retroalimentación de errores temprano y en el momento relevante evitará posibles dolores de cabeza al rastrear por qué falla el código posterior cuando intenta usar rutinas de biblioteca

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-06 22:50:40
?library

Y verás:

library(package) y require(package) ambos cargan el paquete con nombre package y ponlo en la lista de búsqueda. require está diseñado para su uso dentro de otras funciones; devuelve FALSE y da una advertencia (más bien que un error como library() hace por defecto) si el paquete no existir. Ambas funciones comprueban y actualizan la lista de cargadas actualmente paquetes y no recargar un paquete que ya está cargado. (Si usted si desea recargar dicho paquete, llame a detach(unload = TRUE) o unloadNamespace primero.) Si desea cargar un paquete sin poner en la lista de búsqueda, utilice 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-03 21:11:09

Mi teoría inicial sobre la diferencia era que library carga los paquetes ya esté cargado o no, es decir, podría recargar un paquete ya cargado, mientras que require solo comprueba que está cargado, o lo carga si no lo está (por lo tanto, el uso en funciones que dependen de un paquete determinado). La documentación refuta esto, sin embargo, y declara explícitamente que ninguna función recargará un paquete ya cargado.

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-09 15:35:04

Utilice siempre library. Nunca1 utilizar require.

(1 Casi nunca. Tal vez .)

En pocas palabras, esto se debe a que, al usar require, su código podría producir resultados diferentes y erróneos, sin señalar un error. Esto es raro, pero no hipotética! Considere este código, que produce diferentes resultados dependiendo de si {dplyr} se puede cargar:

require(dplyr)

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

Esto puede conducir a resultados sutilmente erróneos. Usando library en lugar de require lanza un error aquí, señalando claramente que algo está mal. Esto es bueno.

También hace que la depuración de todos los otros fallos sea más difícil: Si require un paquete al inicio de su script y usa sus exportaciones en la línea 500, obtendrá un mensaje de error "objeto 'foo' no encontrado" en la línea 500, en lugar de un error "no hay ningún paquete llamado 'bla'".

El único caso de uso aceptable de require es cuando su valor de retorno se comprueba inmediatamente, ya que algunos de las otras respuestas muestran. Este es un patrón bastante común, pero incluso en estos casos es mejor (y recomendado, ver más abajo) separar la comprobación de existencia y la carga del paquete.

Más técnicamente, require en realidad llama a library internamente (si el paquete no estaba ya adjunto - require por lo tanto realiza una comprobación redundante, porque library también comprueba si el paquete ya estaba cargado). Aquí hay una implementación simplificada de require para ilustrar lo que does:

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
}

Los desarrolladores experimentados de R están de acuerdo:

Yihui Xie, autor de {knitr}, {bookdown} y muchos otros paquetes dice: :

Damas y caballeros, he dicho esto antes: require() es la forma incorrecta de cargar un paquete R; use library() en su lugar

Hadley Wickham , autor de los paquetes R más populares que nadie, dice

Use library(x) en scripts de análisis de datos. […] Nunca necesitas para usar require() (requireNamespace() es casi siempre mejor)

 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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-10 11:14:54

Aquí parece estar la diferencia en un paquete ya cargado. Si bien es cierto que tanto require como library no cargan el paquete. Biblioteca hace un montón de otras cosas antes de que se comprueba y sale.

Recomendaría eliminar "require" desde el principio de una función que se ejecuta 2mil veces de todos modos, pero si, por alguna razón, necesitaba mantenerlo. requerir es técnicamente una comprobación más rápida.

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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-12 15:41:08

require() carga todos los paquetes adicionales

 -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/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-10 10:27:19