Всичко зависи от контекста.
::
е основно необходимо, ако има сблъсъци в пространството на имена, функции от различни пакети с едно и също име. Когато зареждам пакета dplyr
, той предоставя функция filter
, която се сблъсква с (и маскира) функцията filter
, заредена по подразбиране в пакета stats
. Така че, ако искам да използвам stats
версията на функцията, ще трябва да я извикам с stats::filter
. Това също дава мотивация да не се зареждат много пакети. Ако наистина искате само една функция от пакет, може да е по-добре да използвате ::
, отколкото да заредите целия пакет, особено ако знаете, че пакетът ще маскира други функции, които искате да използвате.
Не в код, а в текст, намирам ::
за много полезен. Много по-сбито е да въведете stats::filter
от функцията filter
в пакета stats
.
От гледна точка на производителността има (много) ниска цена за използване на ::
. Дългогодишният член на екипа за разработка на R-Core Martin Maechler написа (на r-devel пощенски списък (септември 2017 г.))
Много хора изглежда забравят, че всяко използване на ::
е извикване на R функция и използването му е неефективно в сравнение само с използването на вече импортираното име.
Намаляването на производителността е много малко от порядъка на няколко микросекунди, така че е проблем само когато имате нужда от силно оптимизиран код. Изпълнението на ред код, който използва ::
един милион пъти, ще отнеме секунда или две повече от код, който не използва ::
.
Що се отнася до преносимостта, хубаво е изрично да се зареждат пакети в горната част на скрипт, защото това улеснява хвърлянето на поглед на първите няколко реда и виждането какви пакети са необходими, като ги инсталирате, ако е необходимо, преди да навлезете твърде много в нещо друго, т.е. , преминавайки по средата на дълъг процес, който сега не може да бъде завършен, без да започне отначало.
Настрана: може да се направи подобен аргумент за предпочитане на library()
пред require()
. Библиотеката ще предизвика грешка и ще спре, ако пакетът не е там, докато require ще предупреди, но ще продължи. Ако вашият код има план за извънредни ситуации, в случай че пакетът не е там, тогава непременно използвайте if (require(package)) ...
, но ако вашият код ще се провали без пакет, трябва да използвате library(package)
в горната част, така че да се провали рано и ясно.
В рамките на вашия собствен пакет
Общото решение е да направите свой собствен пакет, който imports
другите пакети трябва да използвате във файла DESCRIPTION. Тези пакети ще бъдат инсталирани автоматично, когато вашият пакет е инсталиран, така че можете да използвате pkg::fun
вътрешно. Или, като ги импортирате също във NAMESPACE
файла, можете да import
цял пакет или избирателно importFrom
специфични функции и да не се нуждаете от ::
. Мненията по този въпрос се различават. Martin Maechler (същият източник на r-devel като по-горе) казва:
Лично аз имам впечатлението, че :: се използва много повече в днешно време, особено в пакети, където силно бих препоръчал използването на importFrom() в NAMESPACE, така че всичко това се случва по време на зареждане на пакета и след това не използвайки ::
в самите източници на пакета.
От друга страна, главният учен на RStudio Хадли Уикъм казва в своята книга R Packages:
Обичайно е пакетите да бъдат изброени в Imports
в DESCRIPTION
, но не и в NAMESPACE
. Всъщност това е, което препоръчвам: избройте пакета в DESCRIPTION
, така че да бъде инсталиран, след което винаги го препращайте изрично с pkg::fun()
. Освен ако няма сериозна причина да не го правите, по-добре е да бъдете изрични.
С двама уважавани R експерти, които дават противоположни препоръки, мисля, че е честно да се каже, че трябва да изберете стила, който ви подхожда най-добре и отговаря на вашите нужди за яснота, ефективност и поддръжка.
Ако често установявате, че използвате само една функция от друг пакет, можете да копирате кода и да го добавите към вашия собствен пакет. Например, имам пакет за лична употреба, който заимства %nin%
от пакета Hmisc
, защото смятам, че е страхотна функция, но не използвам често нищо друго от Hmisc
. С roxygen2
е лесно да добавите @author
и @references
за правилно приписване на кода за заета функция. Също така се уверете, че пакетните лицензи са съвместими, когато правите това.
person
Gregor Thomas
schedule
23.04.2014
require
обикновено се използва в рамките на функция в пакет и тази SO публикация прави добра разлика между него иlibrary
. Ако сте сигурни, че ще имате нужда само от една (или две) функции от пакет,::
е добре, но аз гравитирам към него само когато има сблъсъци в пространството на имената. И не забравяйте за оператора:::
. - person hrbrmstr   schedule 23.04.2014