git add .
git commit -m "Initial commit"
git remote add origin {link to repo}
git branch -M main
git push -u origin main
2 Build your first R package
2.1 Create new R package
2.1.1 Steps
Go to
Files
>New Project…
Select
New Directory
>R Package
Fill in
Package name
Tick
Create a git repository
Click
Create Project
Demo: create new package
2.1.2 Post creation
Install
usethis
anddevtools
Generate a license for your package:
Open-source: run
usethis::use_mit_license(copyright_holder=NULL)
in RStudioConsole
Proprietary:
usethis::use_proprietary_license(copyright_holder)
in RStudioConsole
Other license options…
Generate a read me file: run
usethis::use_readme_rmd()
in RStudioConsole
(optional) Update information inside the
DESCRIPTION
file. Some fields of interest:Title
: what the package doesDescription
: more detailed information about the package (in one paragraph)Depends
: list of package’s dependencies for core functions (your package require these external packages to work)Suggest
: list of package’s dependencies for development tasks or optional functions (for example: packages used for testing)Authors
: list of package’s authors. ReadAuthor
section for the format.
(optional) Upload to Github
Create a new repository on Github
Open
Terminal
(To open Terminal in R studio, clickTools
>Terminal
>New Terminal
)Run the following snippet in RStudio
Terminal
(replace {link to repo} with your repo link)Demo upload github
2.2 Writing the first function
2.2.1 Write it
- Create a file to place your function into. The file must be created in R folder with the naming convention:
function_name.R
. To create the file, there are 2 options:- Use RStudio to navigate to
R
folder and clickNew Blank File
>R Script
- Run
usethis::use_r("filename")
inConsole
- Use RStudio to navigate to
- Define a function
Example: Create a square.R
that contains the following snippet
<- function(x) {
square return(x * x)
}
2.2.2 Document it
Install
roxygen2
Generate and update the roxygen documentation on top of the function. (Refer to demo video)
Run
roxygen2::roxygenise()
ordevtools::document()
to generate documents.
#' Square a number
#'
#' Takes a number x and returns its square, x * x.
#'
#' @param x A numeric value to be squared.
#' @return The square of x.
#' @examples
#' square(2)
#' square(-5.7)
#'
#' @export
<- function(x) {
square return(x * x)
}
Demo: how to generate roxygen skeleton
2.2.3 Caveat (ノ◕ヮ◕)ノ*:・゚✧
Reuse built-in function names instead of creating new ones
Some reusable function names: plot
, print
, toString
To reuse function name:
Modify original function to add class to it
Write a custom function for your class
Example: overriding plot
function for class square
<- function(x) {
square <- x * x
out class(out) <- "square" # tell R that ouptut is of class "square"
return(out)
}
# --- Override plot function
<- function(x, ...) {
plot.square plot(c(1:length(x)), x, xlab = "x", ylab = "Square of x", ...)
}
# --- Test the new plot function
<- square(c(1,2,3,4,5,6,7,8,9,10))
y plot(y)
2.3 Set up quality control
2.3.1 Unit testing
Makes sure your functions work as expected.
Install
devtools
,usethis
Create a test: run
usethis::use_test("test_name")
in RStudioConsole
. This would create a file named"test-test_name.R"
undertests/testthat
folder
Example: unit test for square
function
library(testthat)
test_that("square(3) returns 9", {
# --- Define expected output
<- 9
expected class(expected) <- "square"
# --- Test function
<- square(3)
actual expect_equal(actual, expected)
})
Test passed 🥇
2.3.2 Code coverage
View coverage report locally
Install
covr
Run
covr::report()
Show your test coverage on Github
Import
devtools
andcovr
Push your package to GitHub
Run
use_coverage(type = c("codecov"))
Run
use_github_action("test-coverage")
Login http://codecov.io and get your repo’s token
Run
codecov(token = "YOUR_TOKEN_HERE")
2.3.3 Automatic R CMD check
Test your package locally
Run devtools::check()
in R console to test the package
Ensure your changes doesn’t cause the package to failed to build.
Re-knit readme:
devtools::build_readme()
Run:
::use_github_action_check_standard( usethissave_as = "R-CMD-check.yaml", ref = NULL, ignore = TRUE, open = FALSE)
2.4 Package down
Share your package with the world 🌎.
Install
pkgdown
Run
usethis::use_pkgdown()
Run
usethis::use_pkgdown_github_pages()
Create an empty branch for hosting your page.
- Run the following snippet in Terminal
- To open Terminal in R studio, click
Tools
>Terminal
>New Terminal
git checkout --orphan gh-pages
git rm -rf .
git commit --allow-empty -m 'Initial gh-pages commit'
git push origin gh-pages
git checkout master
2.5 Additional materials
2.5.1 Cheatsheet
2.6 R package with STAN
2.6.1 Quick start
Install
rstantools
andrstan
packagesRun one of the following commands:
rstantools::rstan_create_package(path = "pkgname")
to create new package with STAN functionalityrstantools::use_rstan()
to add STAN functionality to existing package
Store your STAN models (.stan files) under
inst/
folderRun
rstan::config()
after adding STAN models (make sure to do this after adding or updating STAN model)Run
devtools::document()
to compile STAN models. You should find the translated C++ files undersrc/
folderWrite your R function under
R/
folder just like normal, and your STAN models is accessible viastanmodels$model_name
2.6.2 Additional material
Example for a function with STAN functionality:
serosv::hierarchical_bayesian_model()
2.7 Releasing to CRAN
2.7.1 Release workflow
The most concrete expression of the release process is the checklist produced by usethis::use_release_issue()
, which opens a GitHub issue containing a list of todo’s.
The generated checklist would include the following
First release:
usethis::use_news_md()
usethis::use_cran_comments()
Update (aspirational) install instructions in README
Proofread
Title:
andDescription:
Check that all exported functions have
@return
and@examples
Check that
Authors@R:
includes a copyright holder (role ‘cph’)
Prepare for release:
git pull
urlchecker::url_check()
devtools::build_readme()
devtools::check(remote = TRUE, manual = TRUE)
devtools::check_win_devel()
git push
Submit to CRAN:
usethis::use_version('patch')
devtools::submit_cran()
Approve email
Wait for CRAN...
Accepted 🎉
usethis::use_github_release()
usethis::use_dev_version(push = TRUE)
usethis::use_news_md()
But to summarize the process, there are 3 stages for the submission process
Local checks
Run
devtools::check()
and resolve any ERRORs, WARNINGs, and try to not have any NOTEs if possible (as CRAN will not allow some specific NOTEs). After resolving all issues, copy and paste the check result tocran-comments.md
(generated byusethis::use_cran_comment()
)If you find some NOTEs are un-resolvable, make sure to also include the NOTEs and explanation in
cran-comments.md
Make sure to double check documentations following the checklist
Run check on servers
There are several R functions to check package compatibility on other OS
Run
devtools::check_win_devel()
to check your package on a Windows serverRun
devtools::check_mac_release()
to check your package on a MacOS server
If there are any OS-specific issues, make sure to note that in cran-comments.md
as well
Submission
Call
usethis::use_version()
to update your package version number then submit to cran withdevtools::submit_cran()
Wait for CRAN email, but be prepared for several rejections before your package is finally approved
Once you received the approval email, generate a github release using
usethis::use_github_release()
and update version to development mode usingusethis::use_dev_version(push = TRUE)
2.7.2 Common issues and how to resolve them
devtools::check()
don’t like tidyverse syntax (NOTE:
no visible binding for global variable …
) This can be ignored but make sure to include explanation for this NOTE in cran-comments.mdNote regarding package size (
checking installed package size … NOTE
). Similarly, this NOTE can be ignored but require a explanation incran-comments.md
2.7.3 Things that needed to be double check before submission
- Include contributors, references: make sure that you include authors of any code you copied for your package, and any reference for your methodology
- Document your code properly: make sure your roxygen all include @return tag and explain the returned result
2.7.4 Caveats
About DESCRIPTION file
Author
list: if part of your code is derived, copied from other sources, the authors of such code must be included in Author field with ‘ctb’ (contributor) roleDescription
section:When functions are mentioned, make sure it follows the format
function_name()
When packages or software names are mentioned, make sure to place them in single quotes (
'package_name'
)When refer to publication titles, make sure to place them in double quotes (
"publication title"
)
About LICENSE file
Github vs CRAN
LICENSE
file: sinceLICENSE
file for Github and CRAN follows different formats, a work around is to have aLICENSE.md
file for Github and aLICENSE
file for CRAN (make sureLICENSE.md
is in included in.Rbuildignore
). This is usually automatically handled when LICENSE is generated byusethis::use_{license_name}_license()
LICENSE format for Github
# MIT License Copyright (c) 2024 demoPkg authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</details>
LICENSE format for CRAN
YEAR: 2024 COPYRIGHT HOLDER: demoPkg authors
</details>
2.8 Example package
The package used for this tutorial is available at Github
2.9 Resources
A sample R package: https://thinhong.github.io/denim/
Popular R packages: https://tidyverse.tidyverse.org/
Thorough guide to R package development: https://r-pkgs.org
“Advanced R” book: https://adv-r.hadley.nz/”
“R for data science” book : https://r4ds.had.co.nz/
Explore syntax for function documentation: https://roxygen2.r-lib.org/articles/roxygen2.html