В чем разница между require () и library ()?

456

В чем разница между require() и library()?

  • 3
    mail-archive.com/[email protected]/msg00301.html
  • 5
    Добавление ссылки на сообщение в блоге @ Yihui, если он не хочет опубликовать ее версию в качестве ответа. yihui.name/en/2014/07/library-vs-require
Показать ещё 3 комментария
Теги:
packages

9 ответов

278
Лучший ответ

В повседневной работе не так много.

Однако в соответствии с документацией для обеих функций (доступ с помощью ? перед именем функции и нажатием введите), require используется внутри функций, поскольку он выдает предупреждение и продолжает, если пакет не найден, тогда как library выдаст ошибку.

  • 1
    #richiemorrisroe: Спасибо. Означает ли это, что если я загружаю нужные мне пакеты в самом начале своего R-кода, не имеет значения, какой из них я выберу?
  • 6
    до тех пор, пока вы не загружаете пакеты внутри функции, это не имеет значения. Я загрузил все свои пакеты, используя require, и не знал, в чем разница, пока не прочитал справку, увидев ваш вопрос.
Показать ещё 2 комментария
217

Еще одно преимущество require() заключается в том, что оно возвращает логическое значение по умолчанию. TRUE, если пакеты загружены, FALSE, если это не так.

> 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

Таким образом, вы можете использовать require() в конструкциях, подобных приведенным ниже. Что особенно удобно, если вы хотите распространять свой код для нашей установки R, были бы не установлены пакеты.

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")
    }
}
57

Вы можете использовать require(), если вы хотите установить пакеты, если и только при необходимости, например:

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

Для нескольких пакетов вы можете использовать

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

Советы профессионала:

  • При использовании внутри script вы можете избежать диалогового экрана, указав параметр repos install.packages(), например

    install.packages(package, repos="http://cran.us.r-project.org")
    
  • Вы можете обернуть require() и library() в suppressPackageStartupMessages(), чтобы подавить сообщения о запуске пакета, а также использовать параметры require(..., quietly=T, warn.conflicts=F), если это необходимо, чтобы установка была спокойной.

45

В дополнение к уже предоставленному хорошему совету, я бы добавил:

Вероятно, лучше избегать использования require(), если вы фактически не будете использовать возвращаемое им значение, например, в каком-то цикле проверки ошибок, например, заданном thierry.

В большинстве других случаев лучше использовать library(), потому что это даст сообщение об ошибке при загрузке пакета, если пакет недоступен. require() будет просто сбой без ошибки, если пакет отсутствует. Это лучшее время, чтобы узнать, должен ли пакет быть установлен (или, возможно, даже не существует, потому что он не соответствует действительности). Получение обратной связи с обратной связью на раннем этапе и в соответствующее время позволит избежать возможных головных болей с отслеживанием того, почему более поздний код выходит из строя, когда он пытается использовать библиотечные процедуры

15
?library

и вы увидите:

library(package) и require(package) загружают пакет с именем package и поместите его в список поиска. require предназначен для использования внутри других функций; он возвращает FALSE и дает предупреждение (скорее чем ошибка по умолчанию library()), если пакет не существовать. Обе функции проверяют и обновляют список загружаемых в настоящее время пакетов и не перезагружать пакет, который уже загружен. (Если ты хотите перезагрузить такой пакет, вызовите detach(unload = TRUE) или unloadNamespace.) Если вы хотите загрузить пакет без ввода в списке поиска используйте requireNamespace.

9

Всегда используйте library. Никогда 1 использование require.

(1 Почти никогда. Может быть.)

В двух словах это связано с тем, что при использовании require ваш код может давать разные ошибочные результаты, не сигнализируя об ошибке. Это редко, но не гипотетически! Рассмотрим этот код, который дает разные результаты в зависимости от того, может ли быть загружен {dplyr}:

require(dplyr)

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

Это может привести к ошибочным результатам. Использование library вместо require вызывает ошибку здесь, сигнализируя, что что-то не так. Это хорошо.

Это также затрудняет отладку всех других сбоев: если вам require пакет в начале вашего скрипта и использовать его экспорт в строке 500, вы получите сообщение об ошибке "объект" foo not found "в строке 500, а не ошибка", нет пакета под названием "бла".

Единственный приемлемый случай require - когда его возвращаемое значение немедленно проверяется, как показывают некоторые другие ответы. Это довольно распространенный шаблон, но даже в этих случаях лучше (и рекомендуется, см. Ниже) вместо этого разделить проверку наличия и загрузку пакета.

Более технически, require фактически вызывает library внутри (если пакет не было уже подключено - require, таким образом, выполняет избыточную проверку, потому что library также проверяет, был ли уже загружен пакет). Это упрощенная реализация require чтобы проиллюстрировать, что она делает:

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
}

Опытные разработчики R соглашаются:

Yihui Xie, автор {knitr}, {bookdown} и многих других пакетов говорит:

Дамы и господа, я сказал это раньше: require() - неправильный способ загрузки R-пакета; вместо этого используйте library()

Хэдли Уикхэм, автор более популярных пакетов R, чем кто-либо другой, говорит

Используйте library(x) в сценариях анализа данных. [...] Вам не нужно использовать require() (requireNamespace() почти всегда лучше)

7

Моя первоначальная теория о различии заключалась в том, что library загружает пакеты независимо от того, загружена она или нет, т.е. может перезагрузить уже загруженный пакет, а require просто проверяет, что он загружен, или загружает его, если он (таким образом, использование в функциях, которые полагаются на определенный пакет). Однако документация опровергает это и явно указывает, что ни одна из функций не перезагрузит уже загруженный пакет.

  • 13
    это интересно, но на самом деле это не ответ на вопрос ...?
2

Здесь, похоже, разница в уже загруженном пакете. Хотя верно, что оба требуют, и библиотека не загружает пакет. Библиотека выполняет множество других вещей, прежде чем проверяет и завершает работу.

Я бы рекомендовал удалить "require" с начала функции, запущенной в 2 раза в любом случае, но если по какой-то причине мне нужно было ее сохранить. требуют технически более быстрой проверки.

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
  • 0
    Я бы сказал, что это серьезная причина для исправления library реализации (обе функции, которые в настоящее время поставляются с R, являются огромным беспорядком).
  • 0
    @KonradRudolph хорошо, если кто-то собирается исправить библиотеку, возможно, они также могут явно разрешить загрузку по версии и сделать вложение параметром аргумента
Показать ещё 1 комментарий
-8

require() загружает все дополнительные пакеты

  • 8
    Это неверно
  • 0
    Обе функции устанавливают зависимости
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню