R Functions and Package Example

Author

Matthew DeHaven

Published

March 31, 2024

The definitive guide to writing R packages: R Packages (2e)

Writing a Package as a Subfolder of a Project

Why would we want to do this?

  • Organize functions for our project
  • Add documentation for ourselves or for coauthors
  • But we know this package will never be used elsewhere

Create a Project Folder

  • Open a new folder in VS Code, I will call it “my-project”

  • Launch an R terminal, initialize renv and install our VS Code extension packages

my-project >
renv::init()

renv::install("languageserver")
renv::install("jsonlite")
renv::install("nx10/httpgd")

I am going to try to distinguish between what working directory you should use by labelling “my-project >” for the project directory.

  • Now, install the devtools package
my-project >
renv::install("devtools")

Create a New Package

Now we can create our package uisng devtools

my-project >
usethis::create_package("myPackage")

You should see a new folder in your project called “myPackage”.

In addition, your terminal will have now changed to “my-project/myPackage>”

R Package Names

R pacakges have strict naming requirements. You can’t use any “_” or “-” or most other special characters. You can use numbers and “.”, but you can’t start with those symbols. I’d suggest sticking to Camel Case for package names.

Add a function to your package

  • Create a new r script in the “myPackage/R/” folder, called “myfunc.r”
my-project/myPackage/R/myfunc.r
myfunc <- function(a, b) {
  result <- a * b + a
  return(result)
}

Once you save it, open a new terminal with a working directory at your project level.

  • Run the following to instsall and load your package.
my-project >
devtools::install("myPackage")
library(myPackage)
  • Now try to use myfunc() in your project.

It didn’t work!

That’s because we haven’t listed myfunc() to be an exported function of our package. The easiest way to do that is using roxygen2’s comment headers.

Add documentation to your function

  • Go back to the “myfunc.r” script, and add a roxygen2 header.
my-project/myPackage/R/myfunc.r
#' My first function
#'
#' @param a A numerical vector.
#' @param b Also a numerical vector.
#'
#' @return A nmerical vector of a + b * a.
#' @export
#'
#' @examples
#' myfunc(3, 5)
myfunc <- function(a, b) {
  result <- a * b + a
  return(result)
}
  • Save it, then call
my-project/myPackage >
devtools::document()

This will update the documentation of your package. It generates a help file for the function and adds the function to the list of exported functions in the “NAMESPACE” file.

  • Now, go back to your project terminal, reinstall and load the package, and try it out.
my-project >
devtools::install("myPackage")
library(myPackage)
myfunc(3, 5)
?myfunc

You should get a popup help file just like you would for a usual package.

If you call instead help(package = "myPackage") you’ll get an index file of all the exported functions from your package.

Running check()

Whenever you are writing a package you should periodically run

my-project/myPackage >
devtools::check()

This checks a lot of different things about your package

  • is every function documented?
  • is your NAMESPACE file consistent with the packages used?
  • have you set up a license?
  • do the examples actually run?