Каждая домохозяйка должна уметь создать пакет для R!

Для выпечки своего домашнего пакета R потребуется установить пакеты:

Для написания пакета под windows надо установить RTools, под macos/linux устанавливать RTools не требуется.

Первичное создание пакета

  1. Выбрали имя для пакета, пусть будет honey :)

  2. Создали пустую структуру папок для пакета:

devtools::create("где-то там/honey")
setwd("где-то там/honey")
devtools::use_testthat()
  1. В папке honey редактируем файл DESCRIPTION с описанием пакета.
Package: honey
Title: What the Package Does (one line, title case)
Version: 0.0.0.9000
Authors@R: person("Winnie", "Pooh", email = "winnie.the.pooh@dub.com", role = c("aut", "cre"))
Description: What the package does (one paragraph).
Depends: R (>= 3.4.0)
Imports:
  dplyr (>= 0.7.2),
  ggplot2 (>= 2.2.1).
License: GPL-3
Encoding: UTF-8
LazyData: true
RoxygenNote: 6.0.1
Suggests: testthat

Отметим:

  1. В папке honey создаём файл NEWS с описанием истории создания пакета. Мы его будем обновлять при выходе новых версий. Для начала он может быть очень простым:
# honey 0.1
* first public release of the package :)
  1. В подпапке R создаём файл honey.R и пишем в нём описание пакета в целом:
#' honey: package to deal with good and bad bees
#'
#' Extremely important package for every Bear
#'
#' I've written this package a long time ago in a far-far galaxy.
#'
#' @name honey
#' @docType package
NULL
  1. Инициализируем git-репозиторий с двумя ветками: dev и master.

  2. Настраиваем синхронизацию с удалённым github-репозиторием.

Типичный цикл работы над пакетом

  1. Написали очередную новую функцию или отредактировали старую.

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

Перед каждой функцией должна быть написана документация в специальном формате. Например,

#' Evaluates the amount of good honey given the tree
#'
#' Evaluates the amount of good honey given the tree
#'
#' The amount of honey is estimated using the latest mcmc methods.
#'
#' @param tree the tree for which the amount of honey is estimated
#' @return numeric the estimated amount of good honey
#' @export
#' @examples
#' tree <- "Bolshoy Dub"
#' honey_evaluate(tree)
honey_evaluate <- function(tree_name) {
  # ...
  # ...
  return(good_honey_weight)
}

Важно:

  1. Добавили новый встроенный набор данных или обновили старый.

Скажем, мы хотим встроить в пакет набор данных pot:

devtools::use_data(pot)

И после дописываем в honey.R документацию:

#' Data on honey prices
#'
#' A dataset containing xxx The variables are as follows:
#'
#' \itemize{
#' \item pot the number of honey pot
#' \item price the price of the pot in rubbles
#' }
#'
#' @docType data
#' @keywords datasets
#' @name honey_price
#' @usage data(honey_price)
#' @format A data frame with xxx rows and yyy variables
NULL
  1. Подключили пакет и проверили работу функции руками
devtools::load_all()
  1. Написали код, тестирующий функцию

  2. Запустили кучу автоматических тестов

devtools::check()

В результате автоматического анализа мы видим ошибки errors, предупреждения warnings и примечания notes. Ошибки и предупреждения надо исправлять. От примечаний желательно избавляться. Если публиковать пакет на CRAN, то и от примечаний нужно избавиться.

Если нужно запускать только тесты, написанные нами, то

devtools::test()

Проверили стиль кода:

lintr::lint_package()

И можно оценить покрытие пакета тестами:

covr::package_coverage()
  1. Поправили требования в разделе Imports файла DESCRIPTION.

  2. Закоммитили изменения в dev ветку репозитория.

  3. Когда изменений накопилось достаточно создали запрос на перенос изменений из dev ветки в master ветку и одобрили его.

  4. Обновили NEWS файл.

  5. Создаём виньетку к пакету

Скажем, создадим виньетку под названием honey_intro.

devtools::use_vignette("honey_intro")

После редактирования .Rmd-файла виньетки его можно скомпилировать в готовую документацию командой

devtools::build_vignettes()
  1. Выложить пакет на CRAN :)

Установка пакета

Можно поставить пакет из локальной папки

devtools::install()

Любой другой человек сможет установить наш пакет командой

devtools::install_github("username/honey")

здесь вместо username подразумевается гитхабовское имя владельца пакета.

Сырая dev-версия пакета ставится командой

devtools::install_github("username/honey", ref = "dev")

И далее использовать после обычного

library("honey")

Почиташки: