Statistical Computing, 36-350
Friday August 2, 2019
commit
s allow you to take a “snapshot” relative to new lines, modified lines, and deleted linespush/pull
sends the snap shots on your computer to github or brings the snap shots from github to your computer (respectively)“… from user to programmer to contributor, in the gradual progress that R encourages.”
~ John Chambers (Software for Data Analysis: Programming with R)
devtools
/ usethis
can facilitate this process.libPaths()
library()
function.library(tidyverse)
search()
## [1] ".GlobalEnv" "package:forcats" "package:stringr"
## [4] "package:dplyr" "package:purrr" "package:readr"
## [7] "package:tidyr" "package:tibble" "package:ggplot2"
## [10] "package:tidyverse" "package:stats" "package:graphics"
## [13] "package:grDevices" "package:utils" "package:datasets"
## [16] "package:methods" "Autoloads" "package:base"
R provides tools (R CMD INSTALL, R CMD BUILD, R CMD CHECK
, etc…) to move to different stages
library(devtools)
library(usethis)
# documentation
library(roxygen2)
# tests
library(testthat)
devtools
and usethis
allows us to get our package up an running“The goal of devtools is to make package development as painless as possible”
~ Hadley Wickham (R Packages)
install.packages("devtools")
library("devtools")
usethis
focuses on automating repetitive tasks in building packages install.packages("usethis")
library("usethis")
“usethis is a workflow package: it automates repetitive tasks that arise during project setup and development, both for R packages and non-package projects.”
~ usethis
package description
Just like in the version control we are going to us the “Github First” Approach. Here are the reminder of the steps:
In GitHub, do the following:
go to the top-level directory (i.e., github.com/<your user name>)
click on “+” at top right, and select “New repository”
name the repository (e.g., “tartan”)
provide a short description of the repository (don’t leave completely blank!)
keep the repository public (as students you have access to free private repos https://education.github.com/pack, but for purposes of this lab keep the repo public)
click on “Initialize this repository with a README” and select the R option in “Add .gitignore”… there is no need to “Add a license”
click on “Create Repository”
…then RStudio
In RStudio, do the following:
click on File > New Project…
click on “Version Control”, then on “Git”
provide the full address for the “Repository URL” (including the https, etc.; by default, this will provide the name of your local repository)
make sure “Create project as subdirectory of:” points to where you want to point it
click on “Create Project” (in this example we will be calling our package tartan
)
An R (source) package is just files in a directory, formatted in a specific way.
To create the bare bones R package, just type:
usethis::create_package("tartan")
tartan
project, may need to do setwd("../")
, run the above line and then do setwd("tartan")
.This should give us:
R/
man/
NAMESPACE
fileDESCRIPTION
filetartan.Rproj
file (if using RStudio)and anything else you included from intializing your git repo (.gitignore
, LICENSE
, etc)
usethis
creates the “bare minimum” description file
This is fine for now, but becomes more important when you want to release your package
All of your R code goes into the R/
directory. Generally, this code is made up of functions
For example, lets create the file R/welcome.R
and add the function:
usethis::use_r("welcome") # opens up file (creates if need be)
call_scotty_demo <- function(your_name) {
if (nchar(your_name) > 30){
warning("your name is beyond 30 characters, and has been truncated")
your_name <- substr(your_name, 1, 30)
}
name_length <- nchar(your_name)
# Hiiiii
cat(paste("\n",
paste0(c("", rep("-", name_length + 8), "\n"), collapse = ""),
paste0(c("| Hi ", your_name, "! | \n"), collapse=""),
paste0(c("| ", rep("-", name_length + 4), "\n"), collapse = ""),
paste0(c("| /\n")))
)
# from Scotty.
cat(paste0(
" |/ |\\_/| \n",
" | |q p| /} \n",
" | ( 0 )\"\"\"\\ \n",
" \\ |\"-\"` | \n",
" || /=\\\\ | \n",
" \"'\" '\"\"\"'"))
}
Now, we can load the package into memory:
devtools::load_all()
devtools::load_all()
loads your source package into memory
This is important because in developing a package, you often need to re-install the package over and over
Contrasting with the library()
function, which loads (then attaches) already installed packages
?sum
).Rd
files in a man/
directory. The .Rd
look a bit like LaTexThe easiest way to document your R code is roxygen2
package (😱 which we already learned how to use - how useful).
Primarily, this allows you to combine code and documentation into a single file, and handles the .Rd
formatting (and NAMESPACE) for you
install.packages("roxygen2")
library(roxygen2)
#' Meet Scotty, the Scottie Dog
#'
#' @param your_name string of your name (max length 30 characters)
#'
#' @return NULL. Though scotty appears on your screen and says Hi to you.
#' @export
#'
#' @examples
#' call_scotty_demo("Andrew Carnegie")
call_scotty_demo <- function(your_name) {
if (nchar(your_name) > 30){
warning("your name is beyond 30 characters, and has been truncated")
your_name <- substr(your_name, 1, 30)
}
name_length <- nchar(your_name)
# Hiiiii
cat(paste("\n",
paste0(c("", rep("-", name_length + 8), "\n"), collapse = ""),
paste0(c("| Hi ", your_name, "! | \n"), collapse=""),
paste0(c("| ", rep("-", name_length + 4), "\n"), collapse = ""),
paste0(c("| /\n")))
)
# from Scotty.
cat(paste0(
" |/ |\\_/| \n",
" | |q p| /} \n",
" | ( 0 )\"\"\"\\ \n",
" \\ |\"-\"` | \n",
" || /=\\\\ | \n",
" \"'\" '\"\"\"'"))
}
As a standard workflow, we can use:
devtools::document()
man/
folder, and insert the corresponding man/call_scotty_demo.Rd
file that R uses to generate documentation.NAMESPACE
file so when you load your functions you get the desired documenation (need to have @export
)% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/welcome.R
\name{call_scotty_demo}
\alias{call_scotty_demo}
\title{Meet Scotty, the Scottie Dog}
\usage{
call_scotty_demo(your_name)
}
\arguments{
\item{your_name}{string of your name (max length 30 characters)}
}
\value{
\code{NULL}. Though scotty appears on your screen and says Hi to you.
}
\description{
Meet Scotty, the Scottie Dog
}
\examples{
call_scotty_demo("Andrew Carnegie")
}
devtools::load_all()
?call_scotty_demo
Testing is critical to making sure your packages do what you expect.
The easiest way to get started with testing is the testthat
package, which also integrates with devtools
install.packages("testthat")
usethis::use_testthat()
This will set up the tests/testthat
directory where we can store tests
testthat
work?Test-that works hierarchically:
library(testthat)
expect_equal(1, 1)
expect_equal(1, 2)
## Error: 1 not equal to 2.
## 1/1 mismatches
## [1] 1 - 2 == -1
test_that(paste("calling scotty works well (returns null",
"and provides warning nchar > 30)"), {
expect_equal(call_scotty_demo("Oski Bear"), NULL)
expect_warning(call_scotty_demo("Oski Bear, your a wonderful, but slightly creepy Berkeley Bear"))
expect_equal(1, 2)
})
##
## -----------------
## | Hi Oski Bear! |
## | -------------
## | /
## |/ |\_/|
## | |q p| /}
## | ( 0 )"""\
## \ |"-"` |
## || /=\\ |
## "'" '"""'
## --------------------------------------
## | Hi Oski Bear, your a wonderful, b! |
## | ----------------------------------
## | /
## |/ |\_/|
## | |q p| /}
## | ( 0 )"""\
## \ |"-"` |
## || /=\\ |
## "'" '"""'
## Error: Test failed: 'calling scotty works well (returns null and provides warning nchar > 30)'
## * 1 not equal to 2.
## 1/1 mismatches
## [1] 1 - 2 == -1
test
Next, let’s create a file tests/testthat/test-welcome.R
usethis::use_test("welcome")
✔ Setting active project to './tartan'
✔ Adding 'testthat' to Suggests field in DESCRIPTION
✔ Creating 'tests/testthat/'
✔ Writing 'tests/testthat.R'
✔ Writing 'tests/testthat/test-welcome.R'
● Modify 'tests/testthat/test-welcome.R'
What we put in the test-welcome.R
file:
context("test welcome from scotty")
test_that(paste("calling scotty works well (returns null",
"and provides warning nchar > 30)"), {
expect_equal(call_scotty_demo("Oski Bear"), NULL)
expect_warning(call_scotty_demo("Oski Bear, your a wonderful, but slightly creepy Berkeley Bear"))
expect_equal(1, 2)
})
Now run:
devtools::test()
testthat
:This allows users to install your package without being hosted on CRAN.
For example, you could install the R package I just made using:
devtools::install_github(repo = "benjaminleroy/tartan",
force = F)
# so making the sides does do it a ton of times
library(tartan)
#?call_scotty_demo
call_scotty_demo("Big Bird")
##
## ----------------
## | Hi Big Bird! |
## | ------------
## | /
## |/ |\_/|
## | |q p| /}
## | ( 0 )"""\
## \ |"-"` |
## || /=\\ |
## "'" '"""'
Remarkably, the package is available to everyone with an internet connection
Remember, now that we’ve done the basics we can use Rstudio’s built in git and connect to Github to commit all changes and push to Github.
Now check out the Github page, all of the code is there!
Congratulations! You now have your own personal R Package
Including data (can be documented too)
# suppose that I have a tarans dataset that I created - than I can save it this way
usethis::use_data(tartans)
# and document at
usethis::use_r("data")
explore all the things that usethis
automates.
devtools
(high level development tools) useful functions:
devtools::load()
: load package into global environmentdevtools::document()
: document functionsdevtools::test()
: run tests of functionsusethis
(automation): set of desirable functions including use_r
to open up or create a new function file in R/
(similar for use_test
).roxygen2
(commenting): make desirable documentationtestthat
)git
and github
You don’t have to do use the “Github first”, you can find other resources online about how to connect a package to github after you make it (using usethis
even).