## Download R script (here pkg_build_fct.R) containing two sample functions
download.file("https://raw.githubusercontent.com/tgirke/GEN242/main/content/en/tutorials/rpackages/helper_functions/pkg_build_fct.R", "pkg_build_fct.R")
## Build package skeleton based on functions in pkg_build_fct.R
package.skeleton(name="mypackage", code_files=c("pkg_build_fct.R"))Building R Packages
Overview
Motivation for building R packages
- Organization
- Consolidate functions with related utilties in single place
- Interdepencies among less complex functions make coding more efficient
- Minimizes duplications
- Consolidate functions with related utilties in single place
- Documentation
- Help page infrastructure improves documentation of functions
- Big picture of utilties provided by package vignettes (manuals)
- Sharability
- Package can be easier shared with colleagues and public
- Increases code accessibilty for other users
- Extendibility
- Makes software more extensible and maintainable
Package development environments
This page introduces two approaches for building R packages:
R Baseand related functionalitiesdevtoolsand related packages (e.g.usethis,roxygen2andsinew)
The sample code provided below creates for each of the two methods a simple test package that can be installed and loaded on a user’s system. The instructions for the second appoach are more detailed since it is likely to provide the most practical solution for newer users of R.
1. R Base Approach
R packages can be built with the package.skeleton function. The most comprehensive documentation on package development is provided by the Writing R Extensions page on CRAN. The basic workflow example below will create a directory named mypackage containing the skeleton of the package for all functions, methods and classes defined in the R script(s) passed on to the code_files argument. The basic structure of the package directory is described here. The package directory will also contain a file named Read-and-delete-me with instructions for completing the package:
1.1 Create package skeleton
The given example will create a directory named mypackage containing the skeleton of the package for all functions, methods and classes defined in the R script(s) passed on to the code_files argument. The basic structure of the package directory is described here. The package directory will also contain a file named ‘Read-and-delete-me’ with the following instructions for completing the package:
- Edit the help file skeletons in man, possibly combining help files for multiple functions.
- Edit the exports in NAMESPACE, and add necessary imports.
- Put any C/C++/Fortran code in src.
- If you have compiled code, add a
useDynLib()directive toNAMESPACE. - Run R CMD build to build the package tarball.
- Run R CMD check to check the package tarball.
- Read Writing R Extensions for more information.
1.2 Build package
Once a package skeleton is available one can build the package from the command-line (Linux/OS X), or from within R by executing the command-line calls with R’s system("...") command. For instance, the command-line call R CMD build ... can be run from within R with system("R CMD build ..."). The following examples refer to the R console.
1.3 Check package
This will create a tarball of the package with its version number encoded in the file name (here mypackage_1.0.tar.gz). Subsequently, the package tarball needs to be checked for errors with R CMD check.
All issues in a package’s source code and documentation should be addressed until R CMD check returns no error or warning messages anymore.
1.4 Install package
Install package from source on Linux or OS X systems.
Windows requires a zip archive for installing R packages, which can be most conveniently created from the command-line (Linux/OS X) by installing the package in a local directory (here tempdir) and then creating a zip archive from the installed package directory:
This procedure only works for packages which do not rely on compiled code (C/C++). Instructions to fully build an R package under Windows can be found here and here.
1.5 Use package
The following tests the myMAcomp function defined in mypackage. Note, this function was desinged in one of the programming exercises here.
1.6 Maintain package
Several useful helper utilities exist for maintaing and extending packages. Typical package development routines include:
- Adding new functions, methods and classes to the script files in the ./R directory in your package
- Adding their names to the NAMESPACE file of the package
- Additional
.Rdhelp templates can be generated with theprompt()function family like this:
The resulting .Rd help files can be edited in a text editor, and properly rendered and viewed from within R with help of the following functions.
1.7 Submit package to public repository
The best way of sharing an R package with the community is to submit it to one of the main R package repositories, such as CRAN or Bioconductor. The details about the submission process are given on the corresponding repository submission pages:
2. R devtools Approach
Several package develpment routines of the traditional method outlined above are manual, such as updating the NAMESPACE file and documenting functions in separate help (*.Rd) files. This process can be simplified and partially automated by taking advantage of a more recent R package development environment composed of several helper packages including devtools, usethis, roxygen2 and sinew (Wickham and Bryan, n.d.). Many books and web sites document this process in more detail. Here is a small selection of useful online documentation about R package development:
- Book: R Packages by Hadley Wickham and Jenny Bryan
- My First R Package by Fong Chun Chan
- How to Creat an R Package, Easy Mode by Amit Kohli
- Package Development Cheat Sheet
- Automating
roxygen2documentation withsinewby Jonathan Sidi: Blog and CRAN
Workflow for building R packages
The following outlines the basic workflow for building, testing and extending R packages with the package development environment functionalities outlined above.
2.1 Create package skeleton
library("devtools"); library("roxygen2"); library("usethis"); library(sinew) # If not availble install these packages with 'install.packages(...)'
create("myfirstpkg") # Creates package skeleton. The chosen name (here myfirstpkg) will be the name of the package.
setwd("myfirstpkg") # Set working directory of R session to package directory 'myfirstpkg'
use_mit_license() # Add license information to description file (here MIT). To look up alternatives, do ?use_mit_license2.2 Add R functions
Next, R functions can be added to *.R file(s) under the R directory of the new package. Several functions can be organized in one *.R file, each in its own file or any combination. For demonstration purposes, the following will download an R file (pkg_build_fct.R from here) defining two functions (named:myMAcomp and talkToMe) and save it to the R directory of the package.
2.3 Auto-generate roxygen comment lines
The makeOxygen function from the sinew package creates roxygen2 comment skeletons based on the information from each function (below for myMAcomp example). The roxygen comment lines need to be added above the code of each function. This can be done by copy and paste from the R console or by writing the output to a temporary file (below via writeLines). Alternatively, the makeOxyFile function can be used to create a roxygenized copy of an R source file, where the roxygen comment lines have been added above all functions automatically. Next, the default text in the comment lines needs to be replaced by meaningful text describing the utility and usage of each function. This editing process of documentation can be completed and/or revised any time.
2.4 Autogenerate help files
The document function autogenerates for each function one *.Rd file in the man directory of the package. The content in the *.Rd help files is based on the information in the roxygen comment lines generated in the previous step. In addition, all relevant export/import instructions are added to the NAMESPACE file. Importantly, when using roxygen-based documentation in a package then the NAMESPACE and *.Rd files should not be manually edited since this information will be lost during the automation routines provided by roxygen2.
2.5 Add a vignette
A vignette template can be auto-generated with the use_vignette function from the usethis package. The *.Rmd source file of the vignette will be located under a new vignette directory. Additional vignettes can be manually added to this directory as needed.
2.6 Check, install and build package
Now the package can be checked for problems. All warnings and errors should be addressed prior to submission to a public repository. After this it can be installed on a user’s system with the install command. In addition, the build function allows to assemble the package in a *.tar.gz file. The latter is often important for sharing packages and/or submitting them to public repositories.
setwd("..") # Redirect R session to parent directory
check("myfirstpkg") # Check package for problems, when in pkg dir one can just use check()
# remove.packages("myfirstpkg") # Optional. Removes test package if already installed
install("myfirstpkg", build_vignettes=TRUE) # Installs package
build("myfirstpkg") # Creates *.tar.gz file for package required to for submission to CRAN/Bioc2.7 Using the new package
After installing and loading the package its functions, help files and vignettes can be accessed as follows.
Another very useful development function is test for evaluating the test code of a package.
Session Info
R version 4.5.3 (2026-03-11)
Platform: x86_64-pc-linux-gnu
Running under: Debian GNU/Linux 12 (bookworm)
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.11.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.11.0 LAPACK version 3.11.0
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
time zone: America/Los_Angeles
tzcode source: system (glibc)
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] ggplot2_4.0.2 limma_3.66.0
loaded via a namespace (and not attached):
[1] vctrs_0.7.1 cli_3.6.5 knitr_1.51 rlang_1.1.7 xfun_0.56 otel_0.2.0 generics_0.1.4 S7_0.2.1 jsonlite_2.0.0 glue_1.8.0 statmod_1.5.1
[12] htmltools_0.5.9 scales_1.4.0 rmarkdown_2.30 grid_4.5.3 tibble_3.3.1 evaluate_1.0.5 fastmap_1.2.0 yaml_2.3.12 lifecycle_1.0.5 compiler_4.5.3 codetools_0.2-20
[23] dplyr_1.2.0 RColorBrewer_1.1-3 pkgconfig_2.0.3 htmlwidgets_1.6.4 farver_2.1.2 digest_0.6.39 R6_2.6.1 tidyselect_1.2.1 dichromat_2.0-0.1 pillar_1.11.1 magrittr_2.0.4
[34] withr_3.0.2 tools_4.5.3 gtable_0.3.6