ETC5523: Communicating with Data

Stylishly communicating with code

Lecturer: Michael Lydeamore

Department of Econometrics and Business Statistics



Aim

  • Document your functions
  • Create vignettes for your package
  • Distribute your package

Why

  • Documentation informs users of how to use your package
  • Adopting best practice development workflow will make package development easier
  • Distributing your package is needed for adoption of your package by others

Recap of package development

Communicating about your R package

  • What is the goal of the package?
  • What does your function(s) do?
  • How do we use it?
  • Why should we use it?
  • Where do we find and install it?

Documentation is vital

random_number() function

random_number <- function(range) {
  random_numbers <- data.frame(numbers = runif(n = 100, min = 0, max = range))

  ggplot2::ggplot(data = random_numbers, ggplot2::aes(x = numbers)) +
    ggplot2::geom_histogram()
}

random_number(50)

Using our own data

data-raw/census-birthplace.R:

census_birthplace <- read.csv("data-raw/census-birthplace.csv") |>
  dplyr::mutate(birth = factor(birth))

usethis::use_data(census_birthplace, overwrite = TRUE)

Then in a package function:

top_n_birthplace <- function(n, years = c(2016, 2021)) {
  census_birthplace |>
    dplyr::filter(census %in% years) |>
    dplyr::group_by(census) |>
    dplyr::arrange(count) |>
    dplyr::slice(1:n)
}

Using pipe operator in your package

The base pipe (|>) is fine for 99% of cases - I recommend just using that.

If you need the magrittr pipe (%>%) then you can use

usethis::use_pipe()

Including Shiny apps in your package

The process to include a Shiny app is a bit more complicated than data or a function.

Put your app code in inst/[appname]/app.R

In your function to launch your app:

run_app <- function() {
  app_dir <- system.file("ausbirthapp", package = "ausbirthplace")
  shiny::runApp(app_dir, display.mode = "normal")
}

Files in inst/ are installed with your package but are considered “internal”.

The system.file tells R where to look for your shiny app code.

Including Shiny apps in your package

Warning

Don’t include an example for running a shiny app! It will cause R to hang.

Demo

Documentation

Documenting R functions with roxygen2

  • use #' above a function to write documentation for that function
  • roxygen2 uses @ tags to structure documentation, e.g. 
    • any text after @description is the description
    • any text after @param describes the arguments of the function
    • @export signals that it is an exported function
    • any text after @return describes the return object
    • the full list of Rd tags are found here
  • devtools::document() converts the Rd tags to appropriate sections of .Rd files written in the man/ folder

Documenting praise.me package

R/random_number.R

#' Histograms of random numbers
#'
#' Generates 100 uniform random numbers between 0 and `range`, and
#' plots a `ggplot2` histogram.
#'
#' You can modify the plot using
#' ```r
#' random_number(5) + ggplot2::theme_bw()
#' ```
#'
#' @param range **Maximum** value for the uniform distribution
#'
#' @return `ggplot2` histogram of the random values
#' @export
#'
#' @importFrom ggplot2 ggplot aes geom_histogram
#'
#' @examples
#' random_number(12)
random_number <- function(range) {
  random_numbers <- data.frame(numbers = runif(n = 100, min = 0, max = range-1))

  ggplot2::ggplot(data = random_numbers, aes(x = numbers)) +
    geom_histogram()
}

Documenting data

  • usethis::use_data_raw() to store R code to process raw data,
  • usethis::use_data() to save a binary file in data/ directory,
  • The data is named praises.
  • Documentation is contained in data.R or name-of-data.R

Documenting data

R/data.R

#' Number of Australian residents by country of birth from the 2016 and 2021 census
#'
#' @format ## 'census_birthplace'
#' A data frame with 105 rows and 4 columns
#' \describe{
#'   \item{birth}{Country of birth}
#'   \item{count}{Number of residents from that birth country}
#'   \item{percentage}{Percentage of residents from that birth country}
#'   \item{census}{Year of census (either 2016 or 2021)}
#' }
#' @source <https://www.abs.gov.au/websitedbs/censushome.nsf/home/2016>
"census_birthplace"

Make package documentation

  • Add documentation of the “big picture” of your package
usethis::use_package_doc()
  • Above creates the file below

R/ausbirthplace-package.R

#' @keywords internal
"_PACKAGE"

## usethis namespace: start
## usethis namespace: end
NULL
  • Default package documentation is built from your DESCRIPTION file
library(ausbirthplace)
?ausbirthplace

Vignette: a long-form documentation

  • Some documentation doesn’t fit as a package or function documentation.
  • You may want to built a vignette (article) for these cases.
usethis::use_vignette(name = "my-amazing-package", 
                      title = "My amazing package")
  • Edit the created Rmd file
  • Knit the vignette to see what it looks like
  • Use devtools::build() to build package with vignettes included

Dependencies

Adding dependencies

  • Dependencies are specified in DESCRIPTION file under three categories:
    • Depends: Specify the version of R that the package will work with or package that it is dependent on (e.g. for ggplot2 extension packages, it depends on ggplot2).
    • Imports: External packages that are imported to use in your package. Most external packages are in this category.
    • Suggests: Packages that are not strictly needed but are nice to have, i.e. you use them in examples or vignettes.
  • You can add easily add this via usethis::use_package()

Sharing

Share and collaborate on your package

  • Track changes to your code with Git
usethis::use_git()
  • Collaborate with others via GitHub (or otherwise)
usethis::use_github()

or for existing repo, run from the terminal:

git remote add origin https://github.com/user/repo.git
  • You can install your R package now using:
devtools::install_github("user/repo")

Installing praise.me package

devtools::install_github("MikeLydeamore/ausbirthplace")
  • The package is found at https://github.com/MikeLydeamore/ausbirthplace.
  • It’s a good idea to add a README file with installation instructions – this is displayed in the GitHub repo.
  • You can create a README.Rmd file with
usethis::use_readme_rmd() 
# OR usethis::use_readme_md() if you have no code
  • Make sure you knit the README.Rmd when you modify its contents.

Package documentation website with pkgdown

  • Automatically turns all package documentation into a website.
  • Documentation can now be easily viewable outside of R.
  • Easy to customise appearance of the site using YAML

Using pkgdown

usethis::use_pkgdown()
  • Build site locally with pkgdown::build_site()
  • Site appearance is modified in the _pkgdown.yml file
    • bootswatch themes for the appearance of the whole site
    • organising function / vignette documentation with reference
  • See the vignette for more details
  • Automatically build and deploy your site with GitHub actions
usethis::use_pkgdown_github_pages() # if using this, no need for usethis::use_pkgdown()

The whole package development workflow

available::available("pkgname") # check if package name is available (if planning to publish publicly)
usethis::create_package("pkgname")
usethis::use_git() # set up version control
usethis::use_github() # optional
usethis::use_r("myfile")
# write some functions in a script
usethis::use_data_raw() # if adding data
devtools::load_all() # try it out in the console
usethis::use_package("import-pkgname") # add package to import (or depends or suggests)
usethis::use_package_doc() # add package documentation
usethis::use_pipe() # if you want to add %>% from `magrittr`
usethis::use_vignette("vignette-name") # add vignette
devtools::build() # build vignettes
devtools::install() # to install package
devtools::check() # to build and check a package 
usethis::use_readme_rmd() # to add a README Rmd file
styler::style_pkg() # optional (commit first, then review changes carefully)
usethis::use_pkgdown_github_pages() # for setting up pkgdown website on github
# `usethis::use_pkgdown()` if not using github pages

Week 10 Lesson

Summary

  • Package documentation is important to let others know about the goal of the package, what your function does, and how to use your package.
  • Sharing your package by making it easy to install, commiting to good documentation, and making the documentation accessible helps to build trust to use your package.
  • You can make package development and distribution easy with usethis, devtools, roxygen2, and pkgdown.