ExampleRPackage package README.
What you will need for this lesson is:
R
of version at least as new as 3.6
, with 4.*
preferred.R
packages listed in the next subsection.R
files.git
client (either command line or graphical).R CMD
steps.Instructions on how to configure a machine are given here
These steps require some knowledge of working with your computer, network access, disk space, and admin rights. We strongly advise you take the steps in this section before class. We also strongly advise taking the trouble to run these steps. Having full control of a package-enabled R environment is very powerful. Please reach out for help if you are stuck on steps.
Once you have your machine configured start up R
and install the packages we will be using.
There are many systems and tutorials that sit on top of higher order R tools. These can be useful, but, one must remember in R "Writing R Extensions" is the primary source for how to develop R packges.
We assume your machine has a current working R, command-shell (bash / zsh), and text editor (emacs, vim, or other).
Start R and run the following.
install.packages(c( "tinytest", # for running tests "roxygen2", # to generate manuals from comments "knitr", # to generate vignettes from markdown "rmarkdown", # to convert markdown formats, may not need this "wrapr" # example for argument list checking ))
DESCRIPTION # the main project control file R # project source code directory /example_function.R # our example function /package_help.R # package documentation README.Rmd # package documentation source README.md # package documentation, produced from README.Rmd inst # installed items distributed with package /tinytest # package test directory /tinytest/test_ExampleRPackage.R # the one test we have now vignettes # where we place longer documents /Example_Vignette.Rmd # Example markdown document tests # test trigger, do not edit /tinytest.R # test trigger, do not edit .Rbuildignore # file that tells the builder what files to ignore .gitignore # file that tells version control what files to skip NAMESPACE # project imports/exports, produced by roxygen2 man # roxygen2 generated documentation /ExampleRPackage.Rd # generated package documentation /example_function.Rd # generated function documentation ExampleRPackage.Rproj # (optional) config file for RStudio
Point browser to https://github.com/WinVector/ExampleRPackage and press "Fork" in the upper right portion of the page.
base
/zsh
for Linux, MacOS, or Windows with Windows Subsystem for Linux)From a bash
/zsh
command line:
# get a copy of the repository git clone https://github.com/WinVector/ExampleRPackage.git # remove the .git directory to sever it from the original repository cd ExampleRPackage rm -rf .git # start up a new git repository git init . git add -A . git commit -m"example package"
Then associate the package with your own repository by creating an new empty repository on GitHub and following their "preexisting project" instructions (adding a remote).
For all of these steps we are assuming your current directory is the top-level of the package you
are working with. This can be accomplished with the setwd()
command. Alternately one can use an RStudio
project, which largely keeps track of the working directory.
We will run this with our working directory inside our package (please see getwd()
/setwd()
for how to navigate between directories in R). This will produce the file ExampleRPackage_0.1.0.tar.gz
.
library(wrapr) # assumes our current directory is our package # see setwd()/getwd() for how to change directories rebuild_current_package_and_attach <- function( ..., # not used, force later arguments to bind by name package_dir = getwd(), # default to package is current directory. lib = .libPaths()[[1]] # where to attach package ) { wrapr::stop_if_dot_args(substitute(list(...)), "rebuild_current_package") start_time <- date() message(paste("rebuild_current_package working in directory", package_dir)) message(paste("rebuild_current_package working in lib", lib)) # get package name from current directory pkg_name <- tail(strsplit(package_dir, .Platform$file.sep)[[1]], n = 1) message(paste("rebuild_current_package working on package", pkg_name)) # get into a clean state with no package installed/attached detach_str <- paste0('package:', pkg_name) res <- tryCatch(do.call(detach, list(detach_str)), error = function(e) e) if(pkg_name %in% rownames(installed.packages())) { remove.packages(pkg_name, lib = lib) } # regenerate man/.Rd files from roxygen comments res_text <- capture.output(suppressMessages(roxygen2::roxygenize(package.dir = package_dir))) # rebuild a source distribution of package res <- system(paste("R CMD build", package_dir), intern = TRUE) # find the tar name matches <- res[grepl(pkg_name, res)] pkg_pattern <- paste0(pkg_name, '[_.0-9]+', '.tar.gz') matches <- matches[grepl(pkg_pattern, matches)] if(length(matches) != 1) { stop("having trouble finding package tar name from R CMD build output") } str_span <- regexpr(pkg_pattern, matches) tar_name <- substr(matches, str_span, str_span + attr(str_span, 'match.length') - 1) # install the package from the source distribution res_text <- capture.output(install.packages(tar_name, repos = NULL, verbose = FALSE, quiet = TRUE)) # attach package for use res_text <- capture.output(library(pkg_name, character.only = TRUE)) end_time <- date() return(list( pkg_name = pkg_name, tar_name = tar_name, package_dir = package_dir, package_dir = package_dir, lib = lib, start_time = start_time, end_time = end_time )) }
# re-document, re-build, re-install, and re-attach package # write only name of package and tar file name into current work-space (unpack[pkg_name, tar_name] := rebuild_current_package_and_attach()) # rebuild_current_package working in directory /Users/johnmount/Documents/work/ExampleRPackage # rebuild_current_package working in lib /Users/johnmount/Library/R/4.0/library # rebuild_current_package working on package ExampleRPackage # # $pkg_name # [1] "ExampleRPackage" # # $tar_name # [1] "ExampleRPackage_0.1.0.tar.gz" # # $package_dir # [1] "/Users/johnmount/Documents/work/ExampleRPackage" # # $package_dir # [1] "/Users/johnmount/Documents/work/ExampleRPackage" # # $lib # [1] "/Users/johnmount/Library/R/4.0/library" # # $start_time # [1] "Fri Nov 27 11:13:31 2020" # # $end_time # [1] "Fri Nov 27 11:13:35 2020"
# get into state as if last block had been run library(ExampleRPackage) pkg_name <- "ExampleRPackage" tar_name <- "ExampleRPackage_0.1.0.tar.gz"
ls() print(pkg_name) print(tar_name)
Probably want to restart R
at this point and re-attach the package with library(ExampleRPackage)
.
README.md
from README.Rmd
knitr::knit("README.Rmd")
Some time after rebuilding README.md
you may want to rebuild the package again to make sure the new copy is included in the package tar.
This package is already setup to use tinytest
. Existing packages can be configured to work with tinytest
by running tinytest::setup_tinytest('.')
.
# test directory of tests dir <- system.file('tinytest', package = 'ExampleRPackage', mustWork = TRUE) print(dir) test_text <- capture.output(tinytest::run_test_dir( dir, verbose = TRUE, color = FALSE)) cat(paste(test_text, collapse = '\n'))
check_text <- system(paste("R CMD check", tar_name), intern = TRUE) cat(paste(check_text, collapse = '\n'))
example_function(3)
install.packages(tar_name, repos = NULL)
# get this path by copying Github's download link url <- "https://github.com/WinVector/ExampleRPackage/raw/main/ExampleRPackage_0.1.0.tar.gz" install.packages(url, repos = NULL)
remotes::install_github("https://github.com/WinVector/ExampleRPackage")
Submitting to CRAN is a specialized step. First your package must pass all checks and all CRAN rules (most of which are listed in "Writing R Extensions"). It is important to note the following:
For now I am going to leave CRAN submissions as a "to be covered later" topic.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.