Именование функций для пакетов R

Я пишу пакет R и очень хотел бы избежать использования имен функций, найденных в других пакетах. Например, я планировал вызвать функцию «аннотировать», но это уже использовалось в пакете НЛП. Очевидно, что лучше избегать очевидного выбора имени, но существует ли систематический способ поиска в исчерпывающем списке опубликованных имен функций CRAN, чтобы избежать дублирования? Я понимаю, что это в первую очередь важно для общих пакетов CRAN, но это также может быть актуально при локальном обмене на случай конфликта с другим загруженным пакетом.


person Heather Robinson    schedule 22.08.2017    source источник
comment
Возможно, вы можете проверить здесь   -  person akrun    schedule 22.08.2017
comment
Вы можете использовать RDocumentation.   -  person Jaap    schedule 22.08.2017
comment
Спасибо, RDocumentation полезен для поиска имен функций по одному, мне просто интересно, есть ли где-нибудь полный список или способ систематической проверки списка имен функций? Возможно, нет. Спасибо вам обоим за вывеску!   -  person Heather Robinson    schedule 23.08.2017
comment
Пакет sos удобен для поиска помимо пакетов, которыми вы владеете. . Другой вариант — добавить префикс ко всем функциям а-ля stringi (stri_*), stringr (str_*) и т. д.   -  person alistaire    schedule 23.08.2017


Ответы (1)


Конфликты имен возникают при загрузке двух пакетов, содержащих функции с одинаковыми именами. Таким образом, конфликтов имен можно избежать в двух местах:

  • при определении имен функций в пакете
  • при вызове функций из пакета

Создание функций с уникальными именами

На момент написания статьи (23 августа 2017 г.) в CRAN было доступно невероятное количество 11272 пакетов (последние данные можно найти здесь), и новые пакеты добавляются каждый день. .

Таким образом, создание уникальных имен функций сегодня может привести к конфликтам имен в будущем, когда будут добавлены другие пакеты.

Алистер уже упомянул возможность префикса всех ваших функций. Помимо stringi и stringr, пакеты forcats являются еще одним примером, в котором используются префиксы fct_ и lvls_.

Такой подход может значительно снизить вероятность конфликтов имен.

(Хотя не гарантируется, что никакой другой сопровождающий пакета не выберет тот же префикс.)

Однозначный вызов функций с использованием оператора двойного двоеточия

ИМХО, основная ответственность за предотвращение конфликтов имен лежит на пользователе.

Я видел вопросы здесь на SO с более чем полдюжиной загружаемых пакетов. Или для удобства вызывается library(tidyverse), что означает загрузку 19 других пакетов, тогда как dplyr и tidyr было бы достаточно.

Загромождение пространства имен большим количеством загруженных пакетов увеличивает риск конфликтов имен. И даже при загрузке только двух пакетов могут возникнуть конфликты имен. Например, в пакетах lubridate и data.table определены

hour, isoweek, mday, minute, month, quarter, second, wday, week, yday, year

Какая функция вызывается, зависит от порядка загрузки пакетов. (Вы можете использовать conflicts() для поиска объектов, которые существуют с тем же именем в двух или более местах на пути поиска.)

Чтобы избежать двусмысленностей и неожиданных результатов, я предлагаю загружать как можно меньше пакетов и использовать оператор с двойным двоеточием ?"::" для вызова функций из пакетов без предварительной загрузки пакета, например,

library(data.table)
DT <- data.table(t = lubridate::now() + 0:3)
# call function from loaded package data.table
DT[, second(t)] 
[1] 18 19 20 21
# call function from lubridate package
DT[, lubridate::second(t)]
[1] 18.88337 19.88337 20.88337 21.88337

Есть еще одно преимущество использования оператора двойного двоеточия. Он будет служить документацией в коде, из которого вызывается функция.

Это происходит за счет нескольких дополнительных нажатий клавиш, но может сэкономить много времени, когда код проверяется, изменяется или отлаживается через недели или годы. Я видел много вопросов на SO, где ОП не упомянул пакет.

person Uwe    schedule 23.08.2017
comment
Обратите внимание, что использование :: может привести к значительным накладным расходам. В моей системе x <- runif(100); microbenchmark(sum(x), base::sum(x)) это в 20 раз медленнее (правда, всего 5 микросекунд), но если вы делаете это со многими группами, как в DT[, base::sum(x), by=....], это проблема. - person BrodieG; 23.08.2017
comment
@Frank Я перефразировал свой ответ, чтобы лучше указать, что я считаю префиксы хорошей идеей. Спасибо за подсказку. - person Uwe; 23.08.2017
comment
Спасибо всем за ответы, я подумаю об использовании префиксов и проверю пакет sos! - person Heather Robinson; 12.09.2017