Biostatistical Computing, PHC 6068

R package

Zhiguang Huo (Caleb)

Monday Sep 24, 2018

Outline

What is R package

Install R packages

install.packages("mclust")
## try http:// if https:// URLs are not supported
source("https://bioconductor.org/biocLite.R")
biocLite("impute")
install.packages("mclust_5.3.tar",repos=NULL,type="source")
# in R: 
system("R CMD INSTALL mclust")
#command line: R CMD INSTALL mclust
library(devtools)
install_github("cran/mclust")

Why R package

Use R survival package as an example.

Basic structure of an R Package

Play with survival package

library(survival)
help(package = 'survival')
?coxph
browseVignettes("survival")

Simple way to create an R Package – package.skeleton()

Structure of R package

DESCRIPTION

The job of the DESCRIPTION file is to store important metadata about your package. Every package must have a DESCRIPTION. In fact, it’s the defining feature of a package.

DESCRIPTION License

DESCRIPTION Version

Formally, an R package version is a sequence of at least two integers separated by either . or -. For example, 1.0 and 0.9.1-10 are valid versions, but 1 or 1.0-devel are not.

The namespace file in R package

Namespace

base::dim
nrow
dim(mtcars)
dim <- function(x) c(1, 1)
dim(mtcars)
nrow(mtcars)
search()

Man (for manual)

Devtools, starting from sketches.

Red color indicates essential steps

  1. devtools::create() create an new R package
  2. Copy your R code in inside R folder
  3. formatR::tidy_dir() clean up the code
  4. Add documentation in R code
  5. devtools::document() generate R documentation
  6. devtools::use_data() prepare external data
  7. devtools::use_testthat() prepare test functions
  8. devtools::test() preform test
  9. devtools::use_vignette() generate vignettes
  10. devtools::check() check the package
  11. devtools::build() build the package
  12. devtools::install() install the package
  13. others

1. devtools::create() create an new R package

## set working directory to be Desktop
WD <- '~/Desktop'
setwd(WD)

devtools::create("GatorPKG") 
WD2 <- '~/Desktop/GatorPKG'
setwd(WD2)

2. Copy your R code in inside R folder

##' @export
f <- function(x, y) x + y
##' @export
g <- function(x, y) x - y
##' @export
h <- function(x, y) f(x,y) * g(x,y)
##' @export
all <- function(x, y){
  f0 <- f(x,y)
  g0 <- g(x,y)
  h0 <- h(x,y)
  list(f=f0, g=g0, h=h0)
}

3. formatR::tidy dir() clean up the code

setwd(WD2)
## make the code neat
formatR::tidy_dir("R")

4. Add documentation in R code

##' Add up two numbers (Description)
##'
##' We want to add up two numbers, blalala... (Details)
##' @title add two numbers
##' @param x first number
##' @param y second number
##' @return sum of two numbers
##' @author Caleb
##' @export
##' @examples
##' f(1,2)
f <- function(x, y) x + y
##' Subtract two numbers (Description)
##'
##' We want to Subtract two numbers, blalala... (Details)
##' @title Subtract two numbers
##' @param x first number
##' @param y second number
##' @return x - y
##' @author Caleb
##' @export
##' @examples
##' g(2,1)
g <- function(x, y) x - y
##' Complex operations on two numbers (Description)
##'
##' We want to do some complex operations on two numbers, blalala... (Details)
##' @title Very complex operation of two numbers
##' @param x first number
##' @param y second number
##' @return (x - y)(x + y)
##' @author Caleb
##' @export
##' @examples
##' h(3,2)
h <- function(x, y) f(x,y) * g(x,y)
##' Return f,g,h (Description)
##'
##' We want to return f,g,h , blalala... (Details)
##' @title return all
##' @param x first number
##' @param y second number
##' @return A list of f, g, and h.
##' \item{f}{Results for adding}
##' \item{g}{Results for subtracting}
##' \item{h}{Complex Result}
##' @author Caleb
##' @export
##' @examples
##' all(3,2)
all <- function(x, y){
  f0 <- f(x,y)
  g0 <- g(x,y)
  h0 <- h(x,y)
  list(f=f0, g=g0, h=h0)
}

5. devtools::document() generate R documentation

devtools::document() ## default argument is pkg = ".", current working directory

Change:

6. devtools::use_data() prepare external data

xxxx <- sample(1000)
devtools::use_data(xxxx)

Change:

data(xxxx)

6. documenting external data

xxxx.R

#' Prices of 50,000 round cut diamonds.
#'
#' A dataset containing the prices and other attributes of almost 54,000
#' diamonds.
#'
#' @format A data frame with 53940 rows and 10 variables:
#' \describe{
#'   \item{price}{price, in US dollars}
#'   \item{carat}{weight of the diamond, in carats}
#'   ...
#' }
#' @source \url{http://www.diamondse.info/}
"xxxx"

6. internal data

yyyy <- sample(1000)
devtools::use_data(yyyy, internal = TRUE)

7. devtools::use testthat() prepare test functions

devtools::use_testthat() ## default argument is pkg = ".", current working directory
test_that("test if f function is correct", {
    expect_equal(f(1,1), 2)
  }
)

test_that("test if f function is correct", {
    expect_equal(f(1,4), 2)
  }
)

8. devtools::test() preform test

devtools::test() ## default argument is pkg = ".", current working directory

9. devtools::use_vignette() generate vignettes

browseVignettes()
setwd(WD2)
devtools::use_vignette("Gators", pkg = ".")
## or 
setwd(WD)
devtools::use_vignette("Gators", pkg = "GatorPKG")

10. devtools::check() check the package

setwd(WD2)
devtools::check() ## default argument is pkg = ".", current working directory

11. devtools::build() build the package

## build the package
devtools::build() ## default argument is pkg = ".", current working directory

12. devtools::install() install the package

devtools::install() ## default argument is pkg = ".", current working directory
devtools::install(build_vignettes = TRUE) ## also build the vignettes
remove.packages("GatorPKG")
install.packages(file.path("~/Desktop","GatorPKG_0.0.0.9000.tar.gz"),repos=NULL,type="source") ## directly with vignettes

others (internal function)

others (depend on other packages)

others (R package and GitHub)

References