2016-04-20 3 views
0

Я заметил, что некоторые ответы на SO содержат использование pkg::name, где имя обычно является функцией.Основное использование (ы) «pkg :: name»

В чем преимущество этого library(pkg); ... name() или require(pkg); ... name()? R помощь (help("::")) говорит

Для пакета PKG, PKG :: имя возвращает значение экспортируемого имени переменной в пространстве имен упак ... Пространство имен будет загружен, если он не был загружен до вызова , но пакет не будет привязан к пути поиска.

Означает ли это, что функция используется без дополнительной потери памяти загрузки всего пакета (т.е. это эквивалентно import <function> from <package>) в Python? Или это просто способ сказать R использовать функцию из этого пакета, когда могут быть двусмысленности?

Мой вопрос касается использования :: в качестве Rscript или непосредственно в консоли и поэтому не является дубликатом связанного вопроса, как ОР в этом вопросе обсуждается использование функций из stats4 пакета во время разработки пакета проект. С другой стороны, в этом посте, кажется, есть ответы, которые проливают некоторый свет на мой вопрос. Спасибо за ссылку. (Обратите внимание на следующее обсуждение по Meta: duplicates flag)

+0

@ kristang Мой вопрос на самом деле не является дубликатом связанного вопроса, так как ОП в этом вопросе обсуждает использование функций из пакета 'stats4' во время проекта разработки пакета. С другой стороны, в этом посте, кажется, есть ответы, которые проливают некоторый свет на мой вопрос. Спасибо за ссылку. – lmo

+2

Использование '::' будет устранять неоднозначность функций, имеющих одно и то же имя в нескольких пакетах, тогда как обычно используется функция из последнего загруженного пакета. Например, 'library (pryr); library (data.table) ': *" Следующий объект маскируется из 'package: data.table': address "*. В этом случае это не имеет большого значения, потому что функция «address», предоставляемая каждым из этих пакетов, имеет практически одно и то же, но это не всегда так. Любая разница в памяти или производительности между 'library (pkg)' vs 'pkg :: fun', скорее всего, невелика. – nrussell

+1

Соответствующая [дискуссия] (http://r-pkgs.had.co.nz/namespace.html) темы. – nrussell

ответ

4

Это позволяет избежать конфликтов пространства имен, но все равно необходимо загрузить pkg.

Пример => Я сделал это:

pryr::mem_used() 
dplyr::filter(mtcars, cyl==4) 
pryr::mem_used() 

В одном случае R и:

pryr::mem_used() 
library(dplyr) 
filter(mtcars, cyl==4) 
pryr::mem_used() 

в другой.

мем до/после для 1-го было: 27,7 Мб/30,6 Мб мем до/после для второй был: 27,7 MB/30,7 MB

Я не делал несколько тестов или увидеть, если разница была округление или что-то еще, но нет никакой реальной экономии там ИМО.

4

Есть две основные причины, почему я использую эти обозначения:

  • Многозначные: Некоторые пакеты обеспечивают функции, которые имеют такое же имя, как и у базового R или функций из других пакетов. Поэтому загрузка таких библиотек заменяет определенные функции. Этот эффект называется «маскировка». В таких случаях я считаю, что лучший способ кодирования использовать нотацию package::function(), чтобы уточнить, какая из одноименных функций используется, даже если это функция, которая была загружена совсем недавно в пространство имен, и поэтому это не обязательно для получения желаемого выхода. Если функция замаскирована другим пакетом, то это способ только.

    Например, library(raster) содержит (и загружает в пространстве имен) функция, называемая stack(), которая отличается от основания R функции stack() в utils пакете.Чтобы по-прежнему использовать функцию stack() из базы R, она должна быть вызвана с utils::stack() после загрузки библиотеки raster.

  • Доступ к функциям, которые не экспортируются в пространство имен: Этот случай намного реже и немного отличается. Некоторые библиотеки foo.pkg содержат функции, которые не загружаются в пространство имен с library(foo.pkg). В результате, в таких случаях не помогает в доступе к этим функциям.

    Единственный пример, когда я регулярно сталкиваюсь с этой ситуацией, - довольно полезная функция cbind.na() из пакета qpcR. Доступ к нему можно получить только путем указания qpcR:::cbind.na(). Обратите внимание, что в этом случае требуются три двоеточия.

При повторном рассмотрении, также может быть третья причина для меня, чтобы использовать эти обозначения: код компактностью. Если я знаю, что мне понадобится только одна конкретная функция пакета, возможно, только один раз в коде, не интересуясь остальными функциями, предлагаемыми этим пакетом, то я считаю, что обозначение package::function() предпочтительнее. Это может не дать каких-либо ощутимых преимуществ в R, но я принял этот стиль из общих советов на других языках программирования, чтобы избежать загрязнения пространства имен.

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