Tutorial Source Code: github.com/fabarca/r-package-tutorial
Main Reference (Online Book): R Packages - by Hadley Wickham
Cheat Sheet (PDF): Package Development
This is a cheat sheet for creating packages in R. These commands will be explained along this tutorial.
# The first argument of usethis::create_package() must be the path to the new package
# Create package structure
usethis::create_package("PackageName")
# Add some functions inside R/ folder,
# then create documentation and NAMESPACE file
devtools::document()
# Now you can install your packages
devtools::install()
# Create test folder
usethis::use_testthat()
# Add some tests inside tests/testthat/,
# then perform your tests
devtools::test()
# Add a vignette template and dependencies
usethis::use_vignette("vignette-name")
# Install including vignettes
devtools::install(build_vignettes = TRUE)
The aim of this tutorial is to provide a quick start guide to R users interested in creating packages by learning only the essentials. The user is expected to already know how to code in R.
For more details about package creation, please refer to the main reference link.
This Tutorial was written using Rmarkdown, and while it is compiled, it actually creates the R package called ‘firstPkg’. Both, the Rmarkdown file ‘index.Rmd’ and the R package ‘firstPkg’, are available in github.com/fabarca/r-package-tutorial.
These are the packages that you need to install to get started:
install.packages(c("devtools", "roxygen2", "testthat", "knitr", "rmarkdown"))
To have the last version of devtools you may use:
devtools::install_github("hadley/devtools")
First, create a new package folder named firstPkg by using:
usethis::create_package("firstPkg")
## Package: firstPkg
## Title: What the Package Does (One Line, Title Case)
## Version: 0.0.0.9000
## Authors@R (parsed):
## * First Last <first.last@example.com> [aut, cre] (<https://orcid.org/YOUR-ORCID-ID>)
## Description: What the package does (one paragraph).
## License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a
## license
## Encoding: UTF-8
## LazyData: true
## Roxygen: list(markdown = TRUE)
## RoxygenNote: 7.1.1
If you are using Rstudio, the new package project should be opened automatically. Among the files created, will be the DESCRIPTION file, that you can edit with your own information.
This is the basic R package structure:
## DESCRIPTION
## NAMESPACE
## R/
The folder R/ is empty at this moment, all your functions should be placed there.
For example, you can create a script file called groupByDate.R with following code inside:
#' Group Dataframe By Date
#'
#' Return the mean value grouped by date.
#' @param data_frame A data.frame object with two columns: date and value.
#' @return Return a tibble data.frame.
#' @seealso \code{\link{group_by}}, \code{\link{summarise}}
#' @export
#' @importFrom dplyr group_by summarise n %>%
groupByDate <- function(data_frame){
dplyr::group_by(data_frame, date) %>% dplyr::summarise(mean = mean(value), count = dplyr::n())
}
All comments starting by #' are the metadata used by roxygen2 package to automatically create the documentation files (inside the folder man/) and fill the NAMESPACE file.
Before the function definition, you need to add #' @export , in order to make the function available in the NAMESPACE file. This will make the function publicly available, otherwise it would be only accesible from functions within the package.
In this example, you will need to use some functions from a external package. To do that, add a comment like this #' @importFrom other_package function1 function2.
To create documentation based on roxygen2 comments, run the following command:
devtools::document()
## Updating firstPkg documentation
## Loading firstPkg
## Writing NAMESPACE
## Writing groupByDate.Rd
## Documentation completed
Now your package folder should look like this:
## DESCRIPTION
## man/
## man/groupByDate.Rd
## NAMESPACE
## R/
## R/groupByDate.R
Remember to add the external libraries that you need to import in the DESCRIPTION file. In this case you should add this line: Imports: dplyr
To install this package run:
devtools::install()
Now you can check the documentation page of your function using:
?groupByDate
Here is an example code to try the new function:
library(firstPkg)
set.seed(1)
# Create a dataframe
date_vec = rep(as.Date('2017-01-01') + 0:8, 4)
value_vec = sample(1:36 * 4, 36)
example_df = data.frame(date = date_vec, value = value_vec)
# Group the dataframe using the new function
firstPkg::groupByDate(example_df)
## # A tibble: 9 x 3
## date mean count
## <date> <dbl> <int>
## 1 2017-01-01 84 4
## 2 2017-01-02 63 4
## 3 2017-01-03 108 4
## 4 2017-01-04 78 4
## 5 2017-01-05 74 4
## 6 2017-01-06 65 4
## 7 2017-01-07 87 4
## 8 2017-01-08 48 4
## 9 2017-01-09 59 4
To create a test folder using testthat package run:
usethis::use_testthat()
Here you can see the new folders:
## DESCRIPTION
## man/
## man/groupByDate.Rd
## NAMESPACE
## R/
## R/groupByDate.R
## tests/
## tests/testthat.R
## tests/testthat/
Tests must go inside tests/testthat/ folder with the prefix test. For example, you can create a new test script called test_groupByDate.R, with the following code inside:
library(firstPkg)
date_vec = rep(as.Date('2017-01-01') + 0:8, 4)
value_vec = sample(1:36*4, 36)
example_df = data.frame(date = date_vec, value = value_vec)
test_that("Date is well grouped", {
result_df = firstPkg::groupByDate(example_df)
expect_equal(result_df$date, as.Date('2017-01-01') + 0:8)
expect_equal(sum(result_df$count), length(date_vec))
})
test_that("Mean is well calculated", {
result_df = firstPkg::groupByDate(example_df)
expect_equal(mean(result_df$mean), mean(value_vec))
})
To perform the tests run:
devtools::test()
## ✓ | OK F W S | Context
##
⠏ | 0 | groupByDate
✓ | 3 | groupByDate
##
## ══ Results ═════════════════════════════════════════════════════════════════════
## [ FAIL 0 | WARN 0 | SKIP 0 | PASS 3 ]
This is the current directory structure, where almost everything was created automatically. You only had to manually add the R/groupByDate.R and tests/testthat/test_groupByDate.R files, and edit the DESCRIPTION file.
## DESCRIPTION
## man/
## man/groupByDate.Rd
## NAMESPACE
## R/
## R/groupByDate.R
## tests/
## tests/testthat.R
## tests/testthat/
## tests/testthat/test_groupByDate.R
You may also wish to include a vignette in your package. But first, you should have installed “pandoc” software: How to Install Pandoc
If you are using Ubuntu you can try: sudo apt-get install pandoc
Once the requirements are met. You can create a new vignette called firstPkg_intro running:
usethis::use_vignette("firstPkg_intro")
This command creates a template file called firstPkg_intro.Rmd inside vignettes/ folder. It also automatically adds the dependencies in the DESCRIPTION file.
## DESCRIPTION
## man/
## man/groupByDate.Rd
## NAMESPACE
## R/
## R/groupByDate.R
## tests/
## tests/testthat.R
## tests/testthat/
## tests/testthat/test_groupByDate.R
## vignettes/
## vignettes/firstPkg_intro.Rmd
Now you can edit this template with your own code, for example:
---
title: "firstPkg_intro"
author: "Vignette Author"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{firstPkg_intro}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
Here there is an example code for the function groupByDate:
```{r example}
library(firstPkg)
set.seed(1)
date_vec = sample(as.Date('2017-01-01') + 0:6, size = 36, replace = TRUE)
value_vec = as.integer(rnorm(36, mean = 20, sd = 5))
example_df = data.frame(date = date_vec, value = value_vec)
head(example_df)
firstPkg::groupByDate(example_df)
```
To install the package including vignettes run:
devtools::install(build_vignettes = TRUE)
To open the vignette use:
vignette('firstPkg_intro')
Rmarkdown Cheat Sheet: rmarkdown-2.0.pdf
Rmarkdown Reference: rmarkdown-reference.pdf