Recap of Lab 8

Søren Helweg Dam, Daniel Romero

2026

Exercises recap

Lab 8 Learning Objectives

  • Prepare a simple R package for distributing documented functions

  • Explain the terms Repository, Dependency, and Namespace

  • Implement testing in an R package

  • Collaboratively work on an R package on GitHub

Core Concepts

What is an R package?

  • A shareable collection of documented code and/or data

Core Concepts

What is a repository?

  • Specialized storage systems designed to manage source code and other software development assets
  • e.g. a centralized folder with git version control and stored in GitHub

Core Concepts

What is a dependency?

Any external thing your package relies on to work (most commonly, another package).


With usethis, we add dependencies like this:

usethis::use_package("package_name")


We should try to avoid dependencies as much as we can (within reason), because:

  • They increase the size of our package
  • They increase maintenance
  • Can introduce compatibility issues
  • They are rarely completely avoidable

Core Concepts

What is a namespace?

  • A collection of names used to identify specific objects or functions
  • From the perspective of a package, it is the names of every function or data object that will become available when you do library("your_package")
  • R packages export names through the NAMESPACE file:
# Generated by roxygen2: do not edit by hand

export(DNA_to_RNA)
export(amino_acid_counts_plot)
export(random_DNA)
export(subdivide_codons)
export(translate)

Core Concepts

What is a namespace?

  • A collection of names used to identify specific objects or functions
  • From the perspective of a package, it is the names of every function or data object that will become available when you do library("your_package")
  • R packages export names through the NAMESPACE file:
# Generated by roxygen2: do not edit by hand

export(DNA_to_RNA)
export(amino_acid_counts_plot)
export(random_DNA)
export(subdivide_codons)
export(translate)
  • Note: The local namespace of a function is a different thing! You can import functions from other packages into the function’s namespace with @importFrom package function and @import package (we did this in function 5).

The package you built

DESCRIPTION

Package: centralDogma
Type: Package
Title: Central Dogma
Version: 0.1.0
Description: simple R package that replicates the central dogma of molecular biology.
License: MIT + file LICENSE
Encoding: UTF-8
LazyData: true
Imports: 
    ggplot2,
    stringr
Depends:
    R (>= 4.0)

Exercises

Initial setup

  • We created the R package project (RStudio simply creates the minimal files required for an R package)
  • Added basic information to the DESCRIPTION file
  • Connected it to GitHub:
usethis::use_git_remote(name = "origin", "https://github.com/rforbiodatascienceYY/group_X_package.git", overwrite = TRUE)

Registering data objects

Making custom data available to the user of the package

codon_table = c("UUU" = "F", "UCU" = "S", "UAU" = "Y", "UGU" = "C", ...)

usethis::use_data(codon_table, overwrite = TRUE, internal = TRUE)

Implementing functions and their documentation

#' Create a string of random DNA
#'
#' @param DNA_length length of the randomly created DNA
#'
#' @returns a string of random DNA
#' @export
random_DNA <- function(DNA_length){
  DNA_vec <- sample(c("A", "T", "G", "C"), size = DNA_length, replace = TRUE)
  DNA_str <- paste0(DNA_vec, collapse = "")
  return(DNA_str)
}

Those comments on top of the function is how an R package makes its documentation show up when running ?function_name in the Console.

devtools::document() converts those comments into .Rd files in the man folder of the package using roxygen2. Otherwise you would have to write them yourself…

Testing

The purpose of testing:

  • They serve as sanity checks
  • Future proofing: ensure that the behavior doesn’t change when you update your function in the future
  • Ensuring that a bug you fixed doesn’t get re-introduced in a future update
  • Defining the behavior of your function before you even start coding it (test-driven development)

Testing

With testhat, we have a collection of expect_* functions that check for specific conditions

test_that("rnadom DNA has the correct length", {
  DNA_length <- 100
  generated_DNA <- random_DNA(DNA_length)
  
  expect_equal(nchar(generated_DNA), DNA_length)
})

test_that("all letters are valid DNA", {
  DNA_letters <- c("A", "C", "T", "G")

  generated_DNA <- random_DNA(400)
  generated_DNA <- strsplit(generated_DNA, "")[[1]] # transform to vector form
  
  is_valid_letter <- generated_DNA %in% DNA_letters
  expect_true(all(is_valid_letter))
})

Vignettes (group assignment)

  • A vignette is a little “tutorial” that explains the basic functionality of a package
  • It is not a replacement for documentation, but rather a starting point for new users

Errors and challenges

The NAMESPACE file

> devtools::document()
ℹ Updating cdogma documentation
ℹ Loading cdogma
Warning message:
Skipping NAMESPACE
✖ It already exists and was not generated by roxygen2.

The NAMESPACE file

> devtools::document()
ℹ Updating cdogma documentation
ℹ Loading cdogma
Warning message:
Skipping NAMESPACE
✖ It already exists and was not generated by roxygen2.


Solution: Delete NAMESPACE file and rerun devtools::document()

The NAMESPACE file

# Generated by roxygen2: do not edit by hand

<<<<<<< HEAD
export(function_x)
=======
export(function_y)
>>>>>>> e34c9e2848142b2afa6394733438e78434483ebc

The NAMESPACE file

# Generated by roxygen2: do not edit by hand

<<<<<<< HEAD
export(function_x)
=======
export(function_y)
>>>>>>> e34c9e2848142b2afa6394733438e78434483ebc


Solution: Fix merge conflicts

Failing devtools::check()

❯ checking examples ... ERROR
  Running examples in ‘cdogma-Ex.R’ failed
  The error most likely occurred in:
  
  > base::assign(".ptime", proc.time(), pos = "CheckExEnv")
  > ### Name: hello
  > ### Title: Hello, World!
  > ### Aliases: hello
  > 
  > ### ** Examples
  > 
  > hello()
  Error in hello() : could not find function "hello"
  Execution halted

Failing devtools::check()

❯ checking examples ... ERROR
  Running examples in ‘cdogma-Ex.R’ failed
  The error most likely occurred in:
  
  > base::assign(".ptime", proc.time(), pos = "CheckExEnv")
  > ### Name: hello
  > ### Title: Hello, World!
  > ### Aliases: hello
  > 
  > ### ** Examples
  > 
  > hello()
  Error in hello() : could not find function "hello"
  Execution halted


Solution: Delete R/hello.R and man/hello.md