Package Dev Workflow: Starting a New Package

[This article was first published on Ye Olde R Blog Grogram, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Purpose

  • A basic workflow to set up an R package

Disclaimer

Instructions here will rarely be explicit. These workflows are essentially notes for experienced users to help remind them of the minimal steps to complete the task at hand.

Prerequisites

  • Strongish familiarity with RStudio, R packages, and R projects
    • R Packages – contains almost all information to get up and running
  • Medium familiarity with git and github
  • Installation of R, R-Studio, devtools, test_that, and associated dependencies
  • Link Travis and Appveyor accounts to github

Workflow

  • File -> New project -> New directory -> R package -> check create git repository
  • Write functions:
    • Write functions within .R files in /R directory
    • During dev, to interactively work with functions:
      • reinstalled and load package: devtools::load_all() or ctrl-shift-L
    • Add #' @export comment above all functions intended for user
      • ctrl-shift-D or devtools::document() to add function to NAMESPACE
    • External functions:
      • Add package to Imports field of DESCRIPTION using: devtools::use_package("name_of_package")
      • Reference in code as package::function()
      • Best practice – add min version number in DESCRIPTION:

        Imports: 
        dplyr (>= 0.7.5),
      • Frequently used external functions
        • To remove requirement to ref with package::
        • Create imports.R file in /R
        • Populate with:

          #' importFrom package function
          NULL
  • Document ref
    • Add roxygen2 comments above each exported function:

          #' Title (short and descriptive)
          #'
          #' Description (slightly longer)
          #'
          #' Details (longer description)
          #'
          #' @param a description of parameter a
          #' @param b description of parameter b
          #' @return output of function
          #' @export
          #' @examples
          #' # Short example of use
          #' sum(1, 2)
    • (Re-)build documentation: ctrl-shift-D or devtools::document()
    • Helpful tags:

      # Use parameters from other function:
      #' @inheritParams source_function
      
      # Document in another function (useful for directing 
      # class-specific methods to documentation within generic)
      #' @describeIn source_function
      
      # Link to other documentation
      ## If in different package
      #' @seealso \code{\link[package]{function}}
      ## If in same package
      #' @seealso \code{\link{function}}
      
      # Format as code
      #' \code{x}
      
      # To add additional sections
      #' @section SectionName:
      
      # Adding a link
      #' \code{\link{Summary}}
      
      # If you have a family of related functions where every function ]
      # should link to every other function in the family
      #' @family aggregate functions
      
      # Ordered list
      #' \enumerate{
      #'   \item First item
      #'   \item Second item
      #' }
      
      # Unordered list
      #' \itemize{
      #'   \item First item
      #'   \item Second item
      #' }
      
      # Include an example that is not executed when building package
      @examples
      \dontrun{
      sum(1, 2)
      }
  • LICENSE: devtools::use_gpl3_license or devtools::use_mit_license
  • DESCRIPTION:
    • Edit as needed
  • README.Rmd ref
    • devtools::use_readme_rmd
    • Must update .md file after each .Rmd file edit: ctrl+shift+k
  • Vignettes ref
    • devtools::use_vignette("vignette-title")
    • Modify vignette as necessary
    • After each modification: devtools::build_vignettes() or ctrl+shift+k
  • Github
    • Create new repository on github with same name as package
    • Copy commands for pushing an existing repo and enter into RStudio terminal
Push commands

Push commands

  • Testing: ref
    • devtools::use_testthat()
    • Create a .R file for each test in projDir/tests/testthat/
    • Populate with unit testing

      # Describe context at top
      # Example rom tidyr
      # https://github.com/tidyverse/tidyr/tree/master/tests
      context("complete")
      
      test_that("basic invocation works", {
        df <- tibble(x = 1:2, y = 1:2, z = 3:4)
        out <- complete(df, x, y)
        expect_equal(nrow(out), 4)
        expect_equal(out$z, c(3, NA, NA, 4))
      })
    • Run tests: devtools::test() or ctrl + shift + T
  • Continuous integration ref
    • Travis:
      • devtools::use_travis()
      • Flip project repo switch on Travis
      • Add badge to README file

        [![Build Status](https://travis-ci.org/tidyverse/dplyr.svg?branch=master)](https://travis-ci.org/tidyverse/dplyr)
    • AppVeyor:
      • devtools::use_appveyor()
      • Flip project repo switch on AppVeyor
      • Add badge to README file

        [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/tidyverse/dplyr?branch=master&svg=true)](https://ci.appveyor.com/project/tidyverse/dplyr)
  • Checks and cleanup
    • running devtools::check()
    • Consider lintr or formatR to tidy code
      • lintr::lint_package() adds markers to code and allow for manual cleanup

To leave a comment for the author, please follow the link and comment on their blog: Ye Olde R Blog Grogram.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)