R Packages
Notes on the structure of R packages and how to create them, based on R Packages by Hadley Wickham.
help(package = 'my-lovely-package')
gives you a basic overview of what's in the package.
Directory structure:
- R/ (code)
- tests/
- data/
- DESCRIPTION is some metadata: name, version, dependencies
- NAMESPACE
The devtools package will set this up for you.
Bundled packages include HTML and PDF outputs, but not temporary artifacts or anything matched by the contents of .Rbuildignore. They're zipped up.
Turn functions into binary code by calling save()
.
.libPaths()
shows loaded libraries.
Code
Packages are run when they're built. They export packages (objects containing functions) at this time.
.onLoad()
and .onAttach()
can do some setup work for packages.
You can also write .Deprecated("thing-to-use-instead")
Metadata
Uses Debian control format.
- Title
- Version
- Description
- Imports
- Suggests
- Collate (if your code has side-effects)
- LazyData (hmm)
Documentation
This is your library documentation. Use roxygen2.
#' means this comment line is roxygen documentation.
You can include various tags.
You can also incorporate LaTeX.
#' My lovely function #' Which does this #' \code{f} #' \link{some link} #' #' @section My section: #' blah blah blah #' #' @aliases g h i #' @keywords internal #' #' @param x A number. #' @return What it returns. #' @examples #' f(x + y)
To put high level documentation on your package, put some documentation on NULL
:
#' About my package. #' @docType package #' @name package-name NULL
Vignettes
Use R markdown, with some yaml at the top for good measure.
You can use knitr::table() to output tables.
Some people like to do little bits of analysis as packages. You walk the person through your thinking in the vignette, and the rest of the package is helper and support code. See: http://rmflight.github.io/posts/2014/07/analyses_as_packages.html
Tests
Put testthat as a suggested package.
skip()
lets you skip tests.
context("type of test")
lets you describe the tests in your file
Use bquote
, substitute
etc. when making helper functions to avoid having to pass in so much documentation.
Namespaces
Write a NAMESPACE file.
It contains export()
, exportClasses()
and importFrom()
calls (and others…).
roxygen2 + devtools will make this file for us using devtools::document()
.
Write this on an R thing to mark it for export:
#' @export
It's probably easiest to not include imports in the NAMESPACE file, and instead use all imports full qualified as package::fun()
.
Data
Binary
Binary data goes in data/. Make the files in here by calling save()
on R objects (or devtools::use_data()
).
You can put other data here, but .RData files are a good choice.
LazyData: true
in the DESCRIPTION file is important here.
Data is automatically exported.
You should document your datasets with @format
and @source
.
Binary Internal
Again, we use devtools::use_data()
, but with the internal = TRUE
argument. It ends up in R/sysdata.rda.
Text / Raw
Text data goes in inst/extdata
Load it using system.file()
.
Compiled Code
Rcpp is what you'd use to write C++ for R.
The result goes in the src/ directory.
Remember to unload the C code when your package is unloaded.
Use Clang instead of gcc for better error messages.
High Performance Functions with Rcpp
You can also interoperate with Java using rJava, or Fortran. Good luck!
Plain C
You can use .C()
to call any C function, and .Call()
to call one that you have defined an R interface for.
You need to use the SEXP type everywhere.
Installed Files
Things in the /inst directory get copied into the top level directory when the package is installed. Files here can be accessed using system.file()
.