Яка різниця між requ () та library ()?


565

У чому різниця між require()і library()?



7
Додавання посилання на допис у блозі @ Yihui, якщо він не хоче опублікувати його версію як відповідь. yihui.name/ru/2014/07/library-vs-require
MichaelChirico

4
Підсумовуючи повідомлення в блозі @ Yihui: "Пані та панове, я вже говорив це раніше: вимагаю () це неправильний спосіб завантаження пакету R; замість цього використовуйте бібліотеку ()"
De Novo

1
@DanHall ... тому що library()негайно виходить з ладу голосно, рано та з відповідним повідомленням про помилку (якщо пакет не встановлений або не може бути завантажений), тоді require()як помилка не викликає, просто мовчки повертає булеву ЛАЖУ, яку викидають, і змушує код вийти з ладу пізніше та більш виразно з Error: object “bar” not found(скажімо) рядка 175.
smci

1
@KonradRudolph: Готово! Спасибі за ваш відгук.
Марко

Відповіді:


86

Окрім вже наданих гарних порад, я додам:

Мабуть, найкраще уникати використання, require() якщо ви фактично не будете використовувати значення, яке воно повертається, наприклад, в певному циклі перевірки помилок, такому, як дано Thierry.

У більшості інших випадків краще використовувати library(), оскільки це дасть повідомлення про помилку під час завантаження пакета, якщо пакет недоступний. require()просто вийде з ладу без помилки, якщо пакета немає. Це найкращий час, щоб дізнатися, чи потрібно встановити пакунок (чи, можливо, він навіть не існує, оскільки він написаний неправильно). Якщо отримати зворотний зв'язок з помилками рано та у відповідний час, ви уникнете можливих головних болів із відстеженням того, чому пізніше код не працює при спробі використання підпрограм бібліотеки


356

У повсякденній роботі не так багато.

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


1
#richiemorrisroe: Дякую Чи означає це, що якщо я завантажую потрібні мені пакунки на самому початку свого R-коду, не має значення, який з них я виберу?
Марко

6
доки ви не завантажуєте пакети всередині функції, це насправді не має ніякого значення. Я завантажую всі свої пакунки, використовуючи потребу, і не знаю, у чому різниця, поки я не прочитав допомогу, побачивши ваше запитання.
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")
    }
}

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)якщо це необхідно , щоб зберегти INSTALLs тиші.


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 погоджуються:

Yihui Xie , автор {knitr}, {bookdown} та багатьох інших пакунків, говорить :

Пані, панове, я вже говорив це раніше: вимагати () це неправильний спосіб завантаження пакету R; використовуйте натомість бібліотеку ()

Ходлі Вікхем , автор більш популярних R-пакетів, ніж будь-хто інший

Використання library(x)в сценаріях аналізу даних. […] Ніколи не потрібно використовувати require()( requireNamespace()майже завжди краще)


Я хотів би вказати точно так само, якщо ви не викликаєте ВСІ функції з синтаксисом class::function, використовуйте, library()щоб уникнути саме цього.
Привид

19
?library

і ви побачите:

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


9

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


18
це цікаво, але насправді це не відповідь на питання ...?
Бен Болкер


3

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

Я б рекомендував видалити "вимагати" з початку функції, яка працює в 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, що завантажує пакет і повертає його простір імен, не приєднуючи його.
Конрад Рудольф
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.