Недавно я закончил первую версию своего пакета R под названием sdmbench (https://github.com/boyanangelov/sdmbench). Процесс оказался сложнее, чем я думал, но и неожиданным образом. Здесь я дам вам несколько уроков, которые я усвоил на собственном горьком опыте, и надеюсь, что они будут полезны, если вы планируете создать свой собственный пакет.

Начнем с главного:

Зачем вам создавать пакет R

Одна из причин, почему R так популярен в науке о данных, - это количество доступных пакетов с открытым исходным кодом (›10 000 на CRAN ). Даже человек, который работает в тайной сфере, может быть уверен, что найдет хотя бы один пакет, который удовлетворит его / его потребности. Участие в этом огромном сообществе само по себе может стать мощным мотиватором.

Даже если вы более эгоистичны, написание пакетов R может обеспечить вам большую известность, если они станут популярными. Авторитет, полученный от автора пакета, может стать ценным активом в карьере.

И, наконец, это тоже хороший способ организовать свою работу. Часто в науке о данных вы будете повторно использовать многие функции между проектами, и гораздо лучше (сохраняя СУХОЙ) организовать их отдельно и вызывать их из пакета по мере необходимости.

Начиная

Начало может быть ошеломляющим, поскольку написание пакетов включает в себя множество практик разработки программного обеспечения (таких как модульные тесты и документация), которые могут быть незнакомыми. Мне очень помогло чтение очень хорошо организованной электронной книги от Хэдли Уикхема (да, снова его): http://r-pkgs.had.co.nz/. Это было моим справочным руководством на протяжении всего процесса.

Первый шаг - четко определить, какие функции вы хотите включить в пакет, и организовать их соответствующим образом. Здесь важно хорошее именование, и я предпочитаю быть слишком многословным, чем наоборот (взгляните на эту статью). Убедитесь, что вы выбрали правильный уровень абстракции. Большие функции следует разбивать на более мелкие.

Вот примеры хороших и плохих имен объектов из Руководства по стилю Хэдли:

# Good
day_one
day_1
# Bad
first_day_of_the_month
DayOne
dayone
djm1

Документация

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

Тестирование

Как упоминает Хэдли в своей книге, разработчики R часто тестируют свой код вручную. Я предполагаю, что это связано с тем, что R не является языком программирования общего назначения по дизайну, поэтому он часто используется в системах, которые явно не требуют модульных тестов. Тем не менее, вы можете стать очень продуктивным, если напишете тесты заранее. Для этого не обязательно иметь 100% тестовое покрытие. Начните с простого и опирайтесь на свою работу. Обязательно прочтите Разработка через тестирование (TDD). Хорошие тесты также помогут вам с уверенностью провести рефакторинг и отредактировать код. Вот пример теста, показывающий, насколько это может быть просто:

context("String length")
library(stringr)

test_that("str_length is number of characters", {
  expect_equal(str_length("a"), 1)
  expect_equal(str_length("ab"), 2)
  expect_equal(str_length("abc"), 3)
})

Небольшая проблема, с которой я столкнулся, заключается в тестировании функций, которые загружают данные из Интернета. В случае sdmbench у меня была функция, скачивающая данные из GBIF. Эти данные использовались на каждом последующем этапе тестирования, поэтому их нужно было включить в тесты других функций. Это сделало весь процесс довольно длительным (~ 15 мин). Если это станет узким местом во время разработки, вы можете найти обходной путь, загрузив набор данных отдельно и используя его в своем пакете и связанных тестах.

Непрерывная интеграция (CI)

Если у вас нет опыта в традиционной разработке программного обеспечения, скорее всего, вы даже не слышали об этом термине. Инструменты CI предоставляют основу для автоматического запуска пользовательских сценариев в вашем коде. В большинстве случаев вы будете использовать это для автоматического запуска вашего набора тестов всякий раз, когда изменение помещается в репозиторий. Одно из самых популярных (также бесплатных с открытым кодом) решений - Travis CI.

Пакетная виньетка

Документация по пакету содержит инструкции по использованию определенных функций, но она слишком детализирована и не дает полной картины - того, что возможно с пакетом. Виньетка - это документ, описывающий типичный рабочий процесс. В случае sdmbench он показывает, как пользователь может загружать, предварительно обрабатывать, визуализировать данные и сравнивать модели машинного обучения, обученные на них. Вы должны иметь в виду, что виньетка также будет проверяться при сборке пакета, увеличивая время CI.

Следующие шаги и заключительные мысли

Самым важным выводом на дом является то, что вам обязательно стоит подумать о упаковке кода, и это, вероятно, займет больше времени, чем вы думаете!

В качестве следующих шагов вы должны обязательно поделиться своим пакетом на платформах социальных сетей (особенно в Twitter), а еще лучше - связаться с людьми в домене, которым он может быть интересен. В сети (например, на Research Gate) существует множество сообществ исследователей. Вы также можете отправить пакет в ropensci или даже опубликовать его в виде статьи (JOSS). Вы должны, по крайней мере, сделать его цитируемым (например, добавить DOI через Zenodo) и дать ему надлежащую лицензию, чтобы другие могли извлечь выгоду из вашей работы.

Надеюсь, это будет полезно и вы присоединитесь ко мне и многим другим участникам сообщества разработчиков ПО с открытым исходным кодом!