Christopher Gandrud
Build statistical software that is:
The IQSS Best Practices are based on established work in computer science and hard earned experience,
but they (especially IQSSdevtools) are a work in progress.
Suggestions for improvement are highly encouraged!
Don't expect all software projects to necessarily follow the Best Practices.
Instead, think about them as questions you should consider and have good answers to.
RStudio Contains a full developer environment to easily access devtools etc.
NOTE: RStudio is not necessary. You can do all of this in the R Console
File > New Project...
Warning: this is a terrible name for a package
Source Pane
Files Pane
List of files (including regex) for git to ignore
List of files (including regex) for R BUILD to ignore
Machine readable package metadata
Object documentation (probably don't need to edit)
Context for package to look up object names (probably don't need to edit)
RStudio project metadata
R functions
Build Pane
In DESCRIPTION
Package: NewPackage
Type: Package
Title: Practice Building a Package
Version: 0.1.0.9000
Author: YOUR NAME
Maintainer: YOURNAME <yourself@somewhere.net>
Description: Practice building a package.
License: GPL >= 3
Imports:
ggplot2
Encoding: UTF-8
LazyData: true
Roxygen: list(markdown = TRUE)
MAJOR.MINOR.PATCH
In a new file R/beta_plot.R:
#' @import ggplot2
#' @export
beta_plot <- function(n = 10000, a = 1, b = 3) {
# draw distributions
sims <- rbeta(n = n, shape1 = a, shape2 = b)
# convert to data frame for ggplot2 compatability
sims <- data.frame(x = sims)
# plot probability density function
ggplot(sims, aes(x)) +
geom_density() +
xlab("") + ylab("Probability Density Function") +
theme_bw()
}
Note: follow a style guide, e.g. http://adv-r.had.co.nz/Style.html
Code available at: http://bit.ly/2rnDnw2
# load package
library(NewPackage)
# plot various beta distributions
beta_plot(a = 4)
beta_plot(a = 1, b = 2)
# . . . etc . . .
Terminal
git add .
git commit -am "beta_plot added"
RStudio
Stage and click commit
Terminal
git remote add origin https://github.com/USERNAME/NewRepo.git
git push -u origin master
RStudio
git remote add origin https://github.com/USERNAME/NewRepo.git
git push -u origin master
Add GitHub Username and Password
Well-written--fully informative, clear, concise, approachable--documentation is key to:
Documentation that is executable and executed at build.
Ensures that the docs actually works.
Shows users what to expect.
All packages should include a README file in their root directory.
The README should:
# New Package
YOUR NAME
## Motivation
This is a test.
## Examples
The `beta_plot` function allows you to simulate data from a
beta distribution and plot the results.
Ideally the README should include executable RMarkdown examples for dynamic documentation.
R Markdown is Markdown that allows you to include executable code "chunks"
See: https://www.rstudio.com/wp-content/uploads/2016/03/rmarkdown-cheatsheet-2.0.pdf
# Add template README.RMD and
# README.Rmd to .Rbuildignore
devtools::use_readme_rmd()
---
output: md_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r setup, include=FALSE}
knitr::opts_knit$set(
stop_on_error = 2L
)
knitr::opts_chunk$set(
fig.path="man/figures/"
)
```
# New Package
YOUR NAME
## Motivation
This is a test.
## Examples
The `beta_plot` function allows you to simulate data from a
beta distribution and plot the results.
```{r}
library(NewPackage)
beta_plot(a = 1, b = 3)
```
Text
Code available at: http://bit.ly/2reKW40
Document all of the changes made to your package at each version in the NEWS.md file (often called CHANGELOG in other languages)
Provides a standard way of documenting your package where:
#' @import ggplot2
#' @export
beta_plot <- function(n = 10000, a = 1, b = 3) {
# draw distributions
sims <- rbeta(n = n, shape1 = a, shape2 = b)
# convert to data frame for ggplot2 compatability
sims <- data.frame(x = sims)
# plot probability density function
ggplot(sims, aes(x)) +
geom_density() +
xlab("") + ylab("Probability Density Function") +
theme_bw()
}
This is Roxygen
#' Draw values from a beta distribution and plot the probability density
#' function
#'
#' @param n number of observations to draw
#' @param a non-negative alpha parameter of the beta distribution
#' @param b non-negative beta parameter of the beta distribution
#'
#' @import ggplot2
#' @export
beta_plot <- function(n = 10000, a = 1, b = 3) {
# draw distributions
sims <- rbeta(n = n, shape1 = a, shape2 = b)
# convert to data frame for ggplot2 compatability
sims <- data.frame(x = sims)
# plot probability density function
ggplot(sims, aes(x)) +
geom_density() +
xlab("") + ylab("Probability Density Function") +
theme_bw()
}
#' Draw values from a beta distribution and plot the probability density
#' function
#'
#' @param n number of observations to draw
#' @param a non-negative alpha parameter of the beta distribution
#' @param b non-negative beta parameter of the beta distribution
#'
#' @details The Beta distribution with parameters \eqn{a} and \eqn{b} has
#' density:
#'
#' \deqn{
#' \Gamma(a+b)/(\Gamma(a)\Gamma(b))x^(a-1)(1-x)^(b-1)
#' }
#'
#' for \eqn{a > 0}, \eqn{b > 0} and \eqn{0 \le x \le 1}.
#'
#' @seealso \code{\link{rbeta}}, \code{\link{geom_density}}
#' @import ggplot2
#' @export
#' Draw values from a beta distribution and plot the probability density
#' function
#'
#' @param n number of observations to draw
#' @param a non-negative alpha parameter of the beta distribution
#' @param b non-negative beta parameter of the beta distribution
#'
#' @details The Beta distribution with parameters \eqn{a} and \eqn{b} has
#' density:
#'
#' \deqn{
#' \Gamma(a+b)/(\Gamma(a)\Gamma(b))x^(a-1)(1-x)^(b-1)
#' }
#'
#' for \eqn{a > 0}, \eqn{b > 0} and \eqn{0 \le x \le 1}.
#'
#' @examples
#' # Draw from beta distribution with parameters a = 1 and b = 3
#' beta_plot(a = 1, b = 3)
#'
#' @seealso \code{\link{rbeta}}, \code{\link{geom_density}}
#' @import ggplot2
#' @export
Will be run when you check package
?beta_plot
Make the test before making the feature.
Try to include automatically and regularly run tests of your package's full capabilities
This includes both:
Make sure that if your code is going to fail that is does so quickly and informatively.
beta_plot <- function(n = 10000, a = 1, b = 3) {
# draw distributions
sims <- rbeta(n = n, shape1 = a, shape2 = b)
# convert to data frame for ggplot2 compatability
sims <- data.frame(x = sims)
# plot probability density function
ggplot(sims, aes(x)) +
geom_density() +
xlab("") + ylab("Probability Density Function") +
theme_bw()
}
devtools::use_testthat()
Tests in R source files called test-*.R
Calls that apply to all tests (e.g. loading packages used by all tests)
test_that("FAILURE TEST: don't accept a, b, n values <= 0", {
expect_error(beta_plot(a = 0))
expect_error(beta_plot(b = -1))
expect_error(beta_plot(n = -3))
})
In tests/testthat/test-beta_plot.R:
test_that("FAILURE TEST: don't accept a, b, n values <= 0", {
expect_error(beta_plot(a = 0))
expect_error(beta_plot(b = -1))
expect_error(beta_plot(n = -3))
})
In tests/testthat/test-beta_plot.R:
Do these successfully fail?
beta_plot(a = 0)
beta_plot(b = -1)
beta_plot(n = -2)
Warning messages:
1: In rbeta(n = n, shape1 = a, shape2 = b) : NAs produced
2: Removed 10000 rows containing non-finite values (stat_density).
Error in rbeta(n = n, shape1 = a, shape2 = b) : invalid arguments
beta_plot <- function(n = 10000, a = 1, b = 3) {
# ensure non-zero/negative argument values
if (any(n <= 0, a <= 0, b <= 0))
stop("n, a, and b arguments must be greater than 0.", call. = FALSE)
# draw distributions
sims <- rbeta(n = n, shape1 = a, shape2 = b)
# convert to data frame for ggplot2 compatability
sims <- data.frame(x = sims)
# plot probability density function
ggplot(sims, aes(x)) +
geom_density() +
xlab("") + ylab("Probability Density Function") +
theme_bw()
}
test_that("FAILURE TEST: don't accept a, b, n values <= 0", {
expect_error(beta_plot(a = 0),
"n, a, and b arguments must be greater than 0.")
expect_error(beta_plot(b = -1),
"n, a, and b arguments must be greater than 0.")
expect_error(beta_plot(n = -2),
"n, a, and b arguments must be greater than 0.")
})
Create REQUIRE tests (note: not a trivial task with stochastic and graphical output)
Runs tests and CRAN CHECK
CRAN: Comprehensive R Archive Network
#' @import ggplot2
#' @importFrom stats rbeta
#' @export
beta_plot <- function(n = 10000, a = 1, b = 3) {
x <- NULL
# ensure non-zero/negative argument values
if (any(n <= 0, a <= 0, b <= 0))
stop("n, a, and b arguments must be greater than 0.", call. = FALSE)
Now every time you push changes to GitHub:
IQSSdevtools::check_best_practices()
Survey results for NewPackage:
---------------------------------------
Documentation:
readme: yes
roxygen: yes
news: no
bugreports: no
vignettes: no
website:
openscholar: no
pkgdown_website: no
License:
gpl3_license: yes
Version_Control:
git: yes
github: yes
Testing:
uses_testthat: yes
uses_travis: no
uses_appveyor: no
build_check:
build_check_completed: yes
no_check_warnings: yes
no_check_errors: yes
no_check_notes: yes
test_coverage: 100
Background:
package_name: NewPackage
package_version: 0.1.0.9000
package_language: R
package_commit_sha: 59c60f0118650cc77075da0c6f5631894a9e14ce
iqss_bestpractices_version: 0.0.0.9000
iqssdevtools_version: 0.0.0.9000
check_time: 2017-05-30 11:41:59