R Packages Create

An R package is a structured collection of functions, data, and documentation bundled together for easy distribution and reuse. Creating your own package lets you share your tools with colleagues or the world, forces you to write clean documented code, and makes your workflow reproducible.

Package Structure

mypackage/
├── DESCRIPTION        ← package metadata (name, version, author)
├── NAMESPACE          ← what functions to export (auto-generated)
├── R/                 ← all your R function files
│   ├── statistics.R
│   └── plots.R
├── man/               ← documentation (.Rd files, auto-generated)
├── tests/             ← unit tests
│   └── testthat/
├── data/              ← included datasets (.rda files)
└── vignettes/         ← long-form tutorials

Setting Up the Tools

install.packages(c("devtools", "usethis", "roxygen2", "testthat"))
library(devtools)
library(usethis)

Step 1: Create the Package Skeleton

# Creates the folder structure automatically
usethis::create_package("C:/R_Projects/mypackage")

# Or from RStudio: File → New Project → New Directory → R Package

Step 2: Write Your Functions (in R/ folder)

# File: R/statistics.R

#' Calculate the coefficient of variation
#'
#' @param x A numeric vector
#' @param digits Number of decimal places to round to
#' @return Coefficient of variation as a percentage
#' @examples
#' cv(c(10, 20, 30, 40, 50))
#' @export
cv <- function(x, digits = 2) {
  if (!is.numeric(x)) stop("x must be numeric")
  result <- (sd(x) / mean(x)) * 100
  round(result, digits)
}

#' Normalize a numeric vector to 0-1 range
#'
#' @param x A numeric vector
#' @return Normalized vector with values between 0 and 1
#' @export
normalize <- function(x) {
  (x - min(x)) / (max(x) - min(x))
}

The #' comments are roxygen2 documentation. They generate help pages automatically. The @export tag makes the function available when someone loads your package.

Step 3: Fill in DESCRIPTION

Package: mypackage
Title: Useful Statistical Utilities
Version: 0.1.0
Authors@R: person("Your", "Name", email="you@email.com", role=c("aut","cre"))
Description: Provides helper functions for common statistical tasks
             including normalization and coefficient of variation.
License: MIT + file LICENSE
Encoding: UTF-8
Depends: R (>= 4.0.0)
Imports:
    ggplot2,
    dplyr
Suggests:
    testthat (>= 3.0.0)

Step 4: Generate Documentation

devtools::document()
# Reads roxygen2 comments → creates man/*.Rd files
# Updates NAMESPACE automatically

Step 5: Write Tests

usethis::use_testthat()
usethis::use_test("statistics")

# File: tests/testthat/test-statistics.R
test_that("cv returns correct value", {
  expect_equal(cv(c(10,20,30,40,50)), 52.7)
  expect_error(cv("text"), "x must be numeric")
})

test_that("normalize outputs 0 to 1 range", {
  result <- normalize(c(0, 5, 10))
  expect_equal(result, c(0, 0.5, 1))
  expect_true(all(result >= 0 & result <= 1))
})

Step 6: Run Checks and Build

devtools::load_all()    # load package for testing in current session
devtools::test()        # run all tests
devtools::check()       # full CRAN-style check (errors, warnings, notes)
devtools::build()       # build .tar.gz file for distribution

Step 7: Install and Use

devtools::install("C:/R_Projects/mypackage")
library(mypackage)

cv(c(100, 150, 200, 175, 125))   # uses your function
?cv                               # shows your documentation

Adding Data to Your Package

# Create a dataset
sales_data <- data.frame(month=1:12, revenue=c(42,38,51,55,60,72,68,74,80,78,85,92))

usethis::use_data(sales_data)    # saves to data/sales_data.rda

# Add documentation for the dataset in R/data.R:
#' Monthly sales revenue data
#' @format A data frame with 12 rows and 2 columns:
#' \describe{
#'   \item{month}{Month number (1-12)}
#'   \item{revenue}{Revenue in thousands}
#' }
"sales_data"

Publishing to CRAN or GitHub

# Share via GitHub (easier, no CRAN review required)
usethis::use_github()
# Others install with:
# devtools::install_github("yourusername/mypackage")

# CRAN submission (requires passing devtools::check() with 0 errors/warnings)
# Submit at: https://cran.r-project.org/submit.html

Creating a package forces you to write clean, documented, tested code. Even if you never publish it publicly, packaging your own utility functions and sharing them via GitHub is far better than copying functions between scripts. The devtools and usethis packages make the process much faster than it used to be.

Leave a Comment

Your email address will not be published. Required fields are marked *