Загружать пакет только при необходимости в R - PullRequest
13 голосов
/ 01 августа 2011

У меня есть пакет, содержащий целую кучу разных функций (см. Что делать с несовершенными, но полезными функциями? ). Поскольку функции не имеют особого отношения, они зависят от целого ряда других пакетов. Часто во всем пакете будет только одна функция, которая использует другой пакет. Тем не менее, если я использую «Импорт», «Предлагает» или «Зависит» в файле DESCRIPTION, полный список пакетов будет загружаться каждый раз, когда загружается мой пакет, даже если для данного пользователя очень мало таких пакетов.

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

Ответы [ 2 ]

16 голосов
/ 01 августа 2011

Вы можете использовать «Предлагает», а в функции, которой требуется пакет, вы можете добавить код в require() указанный пакет и, если он недоступен, выдать ошибку.Пример, с которым я знаком, веганский пакет, имеет в своем ОПИСАНИИ

Depends: permute
Suggests: MASS, mgcv, lattice, cluster, scatterplot3d, rgl, tcltk

и при загрузке имеющегося у нас пакета:

R> require(vegan)
Loading required package: vegan
Loading required package: permute
This is vegan 1.90-0

и sessionInfo() сообщает, что ни один изПредлагаемые пакеты еще были загружены / прикреплены и т. д .:

R> sessionInfo()
R version 2.13.1 Patched (2011-07-29 r56550)
Platform: x86_64-unknown-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_GB.utf8       LC_NUMERIC=C             
 [3] LC_TIME=en_GB.utf8        LC_COLLATE=en_GB.utf8    
 [5] LC_MONETARY=C             LC_MESSAGES=en_GB.utf8   
 [7] LC_PAPER=en_GB.utf8       LC_NAME=C                
 [9] LC_ADDRESS=C              LC_TELEPHONE=C           
[11] LC_MEASUREMENT=en_GB.utf8 LC_IDENTIFICATION=C      

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] vegan_1.90-0  permute_0.5-0

loaded via a namespace (and not attached):
[1] tools_2.13.1
15 голосов
/ 01 августа 2011

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

  • , используя объявление importFrom в файле пространства имен.importFrom(foo, x, y) сообщает, что функции x и y из пакета foo должны быть импортированы.
  • с использованием оператора двойного двоеточия в вашем коде: foo::bar импортирует функцию bar из пакета foo.например.plyr::ddply(...) получит доступ к функции ddply без загрузки пакета
  • или оператора тройного двоеточия в случае объектов, которые не экспортируются (foo:::bar)

Во всех трех случаях, пакеты должны быть упомянуты в импорте.См. Также соответствующую главу 1.6 и другие в Запись расширений R .

РЕДАКТИРОВАТЬ: Как указывал @Gavin, все это работает только при импорте из пакета с собственным пространством имен.В следующей версии R на (2.14?) Все пакеты должны иметь пространство имен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...