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

565

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

Marco
источник
7
Добавление ссылки на сообщение в блоге @ Yihui, если он не хочет опубликовать ее версию в качестве ответа. yihui.name/en/2014/07/library-vs-require
MichaelChirico
4
Резюмируя сообщение в блоге @ Yihui: «Дамы и господа, я уже говорил это раньше: require () - это неправильный способ загрузки пакета R; вместо этого используйте library ()»
De Novo
1
@DanHall ... потому что library()сразу выходит из строя громко, рано и с соответствующим сообщением об ошибке (если пакет не установлен или не может быть загружен), тогда как require()не вызывает ошибку, просто молча возвращает логическое значение FALSE, которое выбрасывается, и приводит к сбою кода позже и более загадочно Error: object “bar” not foundв (скажем) строке 175.
smci
1
@KonradRudolph: Готово! Спасибо за ваш отзыв.
Марко

Ответы:

87

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

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

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

DWW
источник
356

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

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

richiemorrisroe
источник
1
#richiemorrisroe: Спасибо. Означает ли это, что если я загружаю нужные мне пакеты в самом начале своего R-кода, не имеет значения, какой из них я выберу?
Марко
6
до тех пор, пока вы не загружаете пакеты внутри функции, это не имеет значения. Я загрузил все свои пакеты, используя require, и не знал, в чем разница, пока не прочитал справку, увидев ваш вопрос.
richiemorrisroe
45
Другая причина, которую я использую, requireзаключается в том, что она не позволяет мне ссылаться на пакеты как librariesна практику, которая заставляет R-cognoscenti развиваться. Это libraryкаталог, в котором находятся пакеты.
IRTFM
22
У них есть очень важные различия. Не используйте require, если вы не проверите возвращаемое значение (и в этом случае, как правило, есть лучшие альтернативы, например loadNamespace).
Конрад Рудольф
256

Еще одним преимуществом 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")
    }
}
Thierry
источник
65

Вы можете использовать, 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)
    }
}

Профессиональные советы:

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

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

Даниэль Спаринг
источник
46

Всегда используйте 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 »не найден» в строке 500, а не ошибка «нет пакета с именем« bla »».

Единственный приемлемый вариант использования 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 соглашаются:

Йихуэй Се , автор {knitr}, {bookdown} и многих других пакетов, говорит :

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

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

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

Конрад Рудольф
источник
Я собирался указать точно то же самое, если вы не вызываете ВСЕ функции с синтаксисом class::function, используйте, library()чтобы избежать именно этого.
Призрак
19
?library

и вы увидите:

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

dwstu
источник
9

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

DSB
источник
18
это интересно, но на самом деле это не ответ на вопрос ...?
Бен Болкер,
3

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

Я бы порекомендовал убрать «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
форма
источник
Я бы сказал, что это серьезная причина для исправления реализации library(обе функции, в настоящее время поставляемые с R, представляют собой огромную путаницу).
Конрад Рудольф
@KonradRudolph хорошо, если кто-то собирается исправить библиотеку, может быть, они также могут явно разрешить загрузку по версии и сделать вложение параметром аргумента
Shape
Да, я абсолютно согласен, но это изменит семантику, а не только производительность. В любом случае, к сожалению, управление версиями никогда не будет работать с пакетами в R. Я работаю над заменой этого (правда!). Что касается присоединения, вы можете использовать loadNamespace, который загружает пакет и возвращает его пространство имен, не присоединяя его.
Конрад Рудольф