2016-04-12 2 views
1

Я создаю пакет R, который будет использовать одну функцию от plyr. По this roxygen2 vignette:R с roxygen2: Как использовать одну функцию из другого пакета?

Если вы используете только несколько функций из другого пакета, то рекомендуется опция отметить имя пакета в импорте: поле файла ОПИСАНИЕ и вызовите функцию() в явном виде используя ::, например, pkg :: fun().

Звучит хорошо. Я использую plyr::ldply() - полный звонок с :: - поэтому я перечисляю plyr в Imports: в моем DESCRIPTION файле. Однако, когда я использую devtools::check() я получаю это:

* checking dependencies in R code ... NOTE 
All declared Imports should be used: 
    ‘plyr’ 
    All declared Imports should be used. 

Почему я получаю это примечание?

Я могу избежать записку, добавив @importFrom dplyr ldply в файл, который использует plyr, но потом я заканчиваю, но имея ldply в моем пакете имен. Который я не хочу, и не должен нуждаться, поскольку я использую plyr::ldply() единственный раз, когда я использую эту функцию.

Любые указатели будут оценены!

(This question может быть уместным.)

+0

Является ли 'roxygen2' переписыванием файла' NAMESPACE'? Я считаю, что вам нужно иметь '@import dplyr', чтобы убедиться, что он добавлен автоматически. – cdeterman

+0

Спасибо, что ответили. 'roxygen2' действительно обновляет файл' NAMESPACE'. Я не хочу использовать '@import dplyr', потому что это импортирует все пространство имен dplyr. В соответствии с виньеткой «roxygen2» и другим вопросом, на который я ссылался, мне также не нужно импортировать его. – L42

ответ

7

Если ldply() имеет важное значение для функциональности вашего пакета, то вы хотите в вашем пакете имен. Это точка импорта пространства имен. Функции, которые вам нужны, должны быть в пространстве имен пакетов, потому что именно здесь R будет сначала искать определение функций, а затем пересекать базовое пространство имен и прикрепленные пакеты. Это означает, что независимо от того, какие другие пакеты загружены или выгружены, прикреплены или не подключены, ваш пакет всегда будет иметь доступ к этой функции. В таких случаях используйте:

@importFrom plyr ldply 

И вы можете просто сослаться на ldply() без plyr:: префикса так же, как если бы это была еще одна функция в пакете.

Если ldply() не так уж важно - возможно, он вызывается только один раз в не часто используемой функции - то, Writing R Extensions 1.5.1 дает следующий совет:

Если пакет требуется только несколько объектов из другого пакет, он может использовать полностью квалифицированную ссылку на переменную в коде вместо формального импорта. Полностью квалифицированная ссылка на функцию f в пакете foo имеет вид foo::f. Это немного менее эффективно, чем формальный импорт, а также теряет преимущество записи всех зависимостей в файле NAMESPACE (но их все равно необходимо записать в файле DESCRIPTION). Оценка foo::f приведет к тому, что пакет foo будет загружен, но не подключен, если он уже не был загружен - это может быть преимуществом в задержке загрузки редко используемого пакета.

(я думаю, что этот совет на самом деле немного устарел, так как он подразумевает больше расстояния между DESCRIPTION и NAMESPACE, чем в настоящее время не существует.) Это означает, что вы должны использовать @import plyr и обратитесь к функции, как plyr::ldply(). Но на самом деле это на самом деле предполагает что-то вроде помещения plyr в поле SuggestsDESCRIPTION, что точно не соответствует разметке roxygen2 или точно соответствует R CMD check.

В сумме официальной линией является то, что совет Хэдли (который вы цитируете) предпочтительнее для редко используемых функций из редко используемых пакетов (и/или пакетов, на которые требуется значительное количество времени для загрузки). В противном случае, просто сделать @importFrom как WRE советует:

Использование importFrom выборочно, а не import является хорошей практикой и рекомендуется особенно при импорте из пакетов с более чем дюжиной экспорта.

+0

Благодарим вас за ответ. Проблема возникает, когда я использую '@import packagename' для двух пакетов с функциями с тем же именем. 'devtools :: check()' затем дает что-то вроде этого: «Нашли следующие важные предупреждения: Предупреждение: заменив предыдущий импорт« IRanges :: desc »на« plyr :: desc »при загрузке« mypackage ». Конечно, этого можно избежать, указав импорт с помощью '@ importFrom'. Но как насчет чрезвычайно необычного случая, когда вам нужна функция 'foo' из' packageA' ** и ** функция, называемая 'foo' из' packageB'? При импорте обоих, 'check()' будет жаловаться. Правильно? – L42

+0

@ L42 Это причина использования 'importFrom'. В редком случае, о котором вы упоминаете, будет рассмотрена жалоба R CMD. Одним из решений может быть импорт другой функции из 'packageB' (например,' importFrom (packageB, bar) ', чтобы гарантировать, что пакет установлен и его пространство имен загружено, а затем обратитесь к' packageB :: foo() 'в вашем коде без импорта 'foo'. Другое решение - создать новый однофункциональный пакет, который в основном переименовывает дублируемую функцию с помощью следующего:' newname <- function (...) packageB :: foo (...) ' и затем импортируйте это. – Thomas

+0

Благодарим за помощь. Мне кажется, что невозможно установить пакет, указанный в 'Импорт' в файле' DESCRIPTION', и ** не ** указать его в файле 'NAMESPACE' Я правильно понял это? Если так, то я думаю, что виньетка «roxygen2» и руководство «Написание R Расширений» должны четко указывать это. – L42

Смежные вопросы