Where we left off after part 1:

What we do next:

Documentation for the package itself

We’ve already documented the gday() function. Next, let’s add documentation of the gameday package itself (what you would see with ?gameday). For that, create a new R script and save it as R/gameday.r. The content should be something like

#' My first R package: gameday
#' 
#' A one-line sentence on what this packages does
#' 
#' Single paragraph with more detail on the package.
#' This can span several lines.
#' 
#' @docType package
#' @name gameday
NULL

Vignette

Vignettes allow you to give a broader overview of your package, and show new users what it can be used for and how to use it. Vignettes tell the story of your package. The good news is that, as of R 3.0.0 you can use Rmarkdown to write your vignettes (previously LaTeX was required). It gets better: devtools provides a template for your vignette, to make the process of writing this user-friendly guide as easy as possible:

Suggests: knitr
VignetteBuilder: knitr

to your DESCRIPTION file.

Publish on GitHub

Commit locally

First we have to commit all our files to our local git repository, assuming you haven’t been doing so all along. If you don’t have a Git tab in RStudio, go to Tools > Version Control > Project Setup and choose Git. This will restart RStudio. Then, go to the Git tab, check all files and folders, click commit, add a commit message (eg “my first version of my first R package”) and commit.

Create new, empty GitHub repository

We will now make our package publicly available on GitHub. If we want others to see and use our work we have to make this repository public.

  1. Go to github.com and click on your username (should be on the top right).
  2. Choose Repositories -> New
  3. The repository name is gameday. You can leave Description empty. Choose Public and do NOT initialize with a README.
  4. Copy the address of the repository. For me this is https://github.com/BernhardKonrad/gameday.

Connect local repo to GitHub repo

We have to inform our local Git repository about its companion on GitHub. In Git vocabulary, we need to add a remote. For this, we have to go back to the shell:

  1. Tools > Shell….
  2. We will add the GitHub repository as a remote, using the traditional nickname origin: git remote add origin https://github.com/BernhardKonrad/gameday.
  3. Push your local work, on branch master to the new origin remote and set this remote as the new default: git push -u origin master.
  4. Close the shell, you will now be able to push and pull directly from RStudio.
  5. Your package is now publicly (and freely, remember the License) available to the world.
  6. It gets better: You can actually install your package from GitHub directly:

    library(devtools)
    install_github("BernhardKonrad/gameday")

Tests

We all feel that we should be testing our code. In fact, most of us are, but not in an effective and efficient way:

It’s not that we don’t test our code, it’s that we don’t store our tests so they can be re-run automatically. (Hadley Wickham)

We are used to inspecting our code interactively and smell-testing our data. Formal testing, however, is regarded as very advanced and “not worth it” for the daily work. Turns out, a simple test suit like testthat doesn’t only make testing very easy, but will also make you spend less time fixing bugs and more time writing code.

We will use testthat to add tests to our package. It’s syntax is designed to be very close to english:

# save as test_me.R
test_that("case is ignored", {
expect_equal(gday("canucks"), gday("CANUCKS"))
})

However, it makes sense to set our package up for comprehensive automated testing. Luckily, devtools also has a function for that:

This sets up a handy test structure in the folder tests by adding the folder tests/testthat/ (where our tests will go) as well as the master file tests/testthat.R:

library(testthat)
library(gameday)

test_check("gameday")

It also adds testthat to the Suggests in our DESCRIPTION.

What is there to test about gday()? Since it relies on live data it is a little more challenging to write an informative test, but some useful tests are below. To begin with, we copy our test that checks the case to the new tests/testthat/ folder. Other reasonable tests are:

# save as tests/testthat/test_me.R
test_that("case is ignored", {
  expect_equal(gday("canucks"), gday("CANUCKS"))
})

test_that("always returns logical", {
  expect_is(gday("canucks"), "logical")
})

test_that("asking for the city works just as well", {
  expect_equal(gday("canucks"), gday("Vancouver"))
})

test_that("Seattle does not have a NHL team", {
  expect_false(gday(team="Seattle"))
}

Looks good, let’s run the tests! What are our options:

Once these tests work and pass, I suggest it’s time for a new version number 0.0.0.9001 and a commit & push to GitHub.

Update the R code

There are a couple of things that could be improved in our current implementation.

Add a date argument to gday()

Since the url is so predictable, it is natural to allow the user to specify a second argument date (in the past or future, should default to today’s date) and use gday() to check if her team has a game that day. This will also open the door for more test cases (the schedule in the past is not going to change).

Your turn: Which files do you need to modify to make these changes? What do you need to run next to make your package consistent? Your last step is to Build & Reload the consistent package.

As a bonus, add a check to gday() to make sure the date is entered correctly. Use as.Date (what does it return if an invalid date like “201-411-12” is entered?) and stopifnot(). The following tests should all pass.

context("Check dates")

test_that("Vancouver Canucks had a game against Nashville Predators on 2014-11-02", {
expect_true(gday(team = "canucks", date = "2014-11-02"))
expect_true(gday(team = "predators", date = "2014-11-02"))
})

test_that("Washington Capitals did not play on 2014-11-10", {
expect_false(gday(team = "capitals", date = "2014-11-10"))
expect_false(gday(team = "washington", date = "2014-11-10"))
})

test_that("Wrong date type throws error", {
expect_error(gday("Bruins", date = "201-411-12"), "Error")
})

Finally…

…let’s bump the version to our first minor release 0.1.0 and push everything to GitHub. You can be proud of yourself if you got this far!

back to All the package things