---
title: <font size="10">"All models are wrong, but some are ... well-documented, easy to install and use, reproducible and replicable"!</font>
author: "Helen Kettle, Nick Schurch, Bram Boskamp, David Nutter"
date: "12/05/2020"
output: beamer_presentation
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

```{r,results='hide',echo=FALSE}
library(usethis)
library(devtools)
library(microPop)

```

## Session Overview

* Making your work easier to share... (me)

* Making your results easier for someone to reproduce... (Nick)

* Making sure your work is backed up and easily restored... (Bram)

* And checking to make sure it is actually does what you think it does... (David)


## R-Packaging - (or my gift to my future self)

Why write an R package?

As @drob said on twitter:

**"I wish I'd left this code across scattered .R files instead of combining it into a package" said no one ever #rstat** (19/07/2015)


And that is basically it!
If you put your code into a package you can:

* share it easily, 
* document it easily 
* and when you come to use it again in the future you don't have to wade through tens of R files trying to work out which one you were using.

## Tools
There are a few tools which make writing an R package (almost) painless:

* devtools (R package for development)
* roxygen2 (R package for documentation)
* testthat (R package for testing)
* Rmarkdown (writing vignettes)

## Basic Framework

```{r, eval=FALSE}
library(devtools)
library(roxygen2)
library(testthat)

create('myPackage')

document() #use roxygen2 to make documentation

use_vignette('tutorial')#set up vignette folder 
                        #and tutorial.Rmd
build_vignettes() #compile your R markdown file(s)

use_testthat() #set up testing folders
test() #run tests

check() #run CRAN checks
build() #create myPackage.tar.gz which 
        #can be uploaded to CRAN/github/friend
```

## Making an R package from scratch

Taken from the excellent blog post by Hilary Parker:
<https://hilaryparker.com/2014/04/29/writing-an-r-package-from-scratch/>

Let's say you have one R function called kitten_function (Hilary used cats but cats can be a bit cantankerous in my experience!)

```{r, echo=TRUE}
kitten_function <- function(love=TRUE){
    if(love==TRUE){
        print("I love kittens!")
    }
    else {
        print("I am not a cool person.")
    }
}
```

## Let's add some documentation (roxygen2)

```{r}
#' A Kitten Function
#'
#' This function allows you to express your love of kittens.
#' @param love Do you love kittens? Defaults to TRUE.
#' @export
#' @examples
#' kitten_function(FALSE)
 
kitten_function <- function(love=TRUE){
    if(love==TRUE){
        print("I love kittens!")
    }
    else {
        print("I am not a cool person.")
    }
}
```

## Creating an R package
```{r, eval=FALSE, echo=TRUE}
library(devtools)
library(roxygen2)
library(testthat)

create('Kittens')
```
* This makes 2 folders ('R' and 'man') and a file called DESCRIPTION
* Put your functions (.R files) in 'R'
* The 'man' folder contains .Rd files which are documentation files automatically created by roxygen2
* You edit the DESCRIPTION file to describe your package

```{r, eval=FALSE}
document()
```


## Testing using testthat 

- Units tests allow you to test one specific piece of code (e.g. a function)
- Sometimes it's really hard to test a function. 
    - Is your function is too unweidly? Break it down/refactor? 
- Writing tests can really help improve your code
- Often you need to run some code before you can use the function. 
    - If this is true for many functions then I write a script that runs the model for different scenarios then I make tests for these different scenarios (use flags to avoid re-running code)
- When you do code updates running all your unit tests gives you peace of mind you haven't broken your code
```{r, eval=FALSE}
use_testthat()
test()
```

## Error Catching - VERY IMPORTANT!!!

Possibly the thing that takes the longest. But you will thank your past self soooo much!

R error messages can be cryptic when they are reporting an error in your package so take some time to write an informative error message

## Informative error messages will save you hours in the future!

```{r, echo=FALSE}
library(microPop)
Bug1=createDF('Microbe1.csv')
```

E.g. if the user needs to load a data frame, here called Bug1:
```{r, echo=FALSE}
print(Bug1)
```

---

```{r,eval=FALSE}

Bug1['halfSat','Banana']=NA #put in an error
```

We may have many different Bug dataframes with different substrates which are called generically so we want the error message to let us know where the problem is, e.g.

```{r, eval=FALSE}
substrate ='Banana'
DF='Bug1'

if (is.na(get(DF)['halfSat',substrate])){
    stop(paste('MyPackage ERROR: halfSat for',substrate,
               'in data frame',DF,'is NA. 
               Please change to a number' ))
}
```
Error: MyPackage ERROR: halfSat for Banana in data frame Bug1 is NA. Please change to a number


## Vignettes
- A vignette is a getting-started type of documentation
   - E.g. a tutorial with examples of the kind of problems the package can solve and how to solve them
- A package can have multiple vignettes - e.g. basic and advanced
- R markdown is perfect for vignettes (also to test code)  


```{r, eval=FALSE}
devtools::use_vignette()
devtools::build_vignettes()
```


## CRAN checks
All the hoops your package has to jump through before it will accepted by CRAN

http://r-pkgs.had.co.nz/check.html

```{r, eval=FALSE}
devtools::check()
```

I use linux so I also use the windows platform check website:

https://win-builder.r-project.org/

## Sharing your package

To create a myPackage.tar.gz file that you can install your package from use:

```{r, eval=FALSE}
devtools::build() 
```
This can be uploaded to CRAN, github, emailed to a friend so they can use

```{r, eval=FALSE}
install.packages(myPackage.tar.gz, repos = NULL, 
                 type =‘‘source’’)
```

## Further Resources

- Overview: https://rawgit.com/rstudio/cheatsheets/master/package-development.pdf
- Writing vignettes: http://r-pkgs.had.co.nz/vignettes.html
- Using devtools: 

   - https://uoftcoders.github.io/studyGroup/lessons/r/packages/lesson/ 
   - https://devtools.r-lib.org/
   

## Summary

- It's pretty easy to make an R-package
   - some overhead but big payoff
   
- Once you start you can't stop!
    - easy to do updates
    - easy to share
    - easy for you to use with lots of different projects
    - great feeling if people start using it!
    
