If you have a Windows machine, you need to install RTools from https://cran.r-project.org/bin/windows/Rtools/ (choose the frozen one).
Try the pak::pkg_name_check function (available::available superceded):
pak::pkg_name_check("ggplot")
## ╔══════════════════════════════════════════════════════════════════════════════╗ ## ║ –*– ggplot –*– ║ ## ╚══════════════════════════════════════════════════════════════════════════════╝ ## ┌──────────────────────────────────────────────────────────────────────────────┐ ## │ ✔ valid name ✖ CRAN ✔ Bioconductor ✔ not a profanity │ ## └──────────────────────────────────────────────────────────────────────────────┘ ## ┌ Wikipedia ───────────────────────────────────────────────────────────────────┐ ## │ Ggplot2 (from Ggplot) ggplot2 is an open-source data visualization package │ ## │ for the statistical programming language R. Created by Hadley Wickham in │ ## │ 2005, ggplot2 is an implementation of Leland Wilkinson's Grammar of │ ## │ Graphics—a general scheme for data visualization which breaks up graphs │ ## │ into semantic components such as scales and layers. ggplot2 can serve as a │ ## │ replacement for the base graphics in R and contains a number of defaults │ ## │ … │ ## └─────────────────────────────────────── https://en.wikipedia.org/wiki/Ggplot2 ┘ ## ┌ Wiktionary ──────────────────────────────────────────────────────────────────┐ ## │ ggplot No English definition found │ ## └──────────────────────────────────────────────────────────────────────────────┘ ## ┌──────────────────────────────────────────────────────────────────────────────┐ ## │ Sentiment: 😐 (0) │ ## └──────────────────────────────────────────────────────────────────────────────┘
Use RStudio and the devtools and usethis packages. It’s easier.
install.packages(c("devtools", "usethis"))
In RStudio, File -> New Project -> New Directory -> R Package with devtools (scroll down), with a name:
This is so people (including you on the cluster) can:
usethis::use_git() # make a Git repo usethis::use_github() # must have GITHUB_PAT set up usethis::use_github(protocol = "https") # must have GITHUB_PAT set up
…but it’s worthwhile. Writing out argument definitions makes it easier to identify if argument names make sense.
Go to Build -> Configure Build Tools. Click Generate documents with Roxygen. If that is gray, install roxygen2:
install.packages("roxygen2")
Click “Configure” - click all the boxes.
In the RStudio project, go to “Go to file/function” search bar on the menu bar.
Type “DESCRIPTION” and open that file.
Title - What the Package Does (Title Case)Authors@R: c(person("first", "last")) - usethis::use_author()
comment = c(ORCID = "ORCID-ID")Description: Use paragraph prose here. Don't start with word package Use 2-4 spaces when indenting paragraphs within the Description.usethis::use_*_licenseI add this to the DESCRIPTION file:
Authors@R: c(person(given = "John",
family = "Muschelli",
email = "[email protected]",
role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-6469-1750")))
Use Authors@R even if there is only one author.
usethis::use_gpl3_license("John Muschelli")
library or require in functions in a packagebase package needs to be imported (stats, methods)R(>=RVERSION)
usethis::use_package("tidyr", type = "Imports")
usethis::use_package("dplyr", type = "Suggests")
DESCRIPTION file)Description field so that it’s a sentence and it ends with a period.<http...>). Use DOIs if you can." ".Roxygen allows for functions and documentation in the same file. Let’s make a function:
top = function(x, n) {
xx = x[1:n, 1:n]
hist(xx)
print(xx)
}
Save this to top.R file in R/ (where R functions are).
Highlight the code of a function definition:
top = function(x, n) {
Go to Code -> Insert Roxygen Skeleton
#' Title #' #' @param x #' @param n #' #' @returns #' @export #' @examples
@param stands for a parameter/argument for that function.@returns denotes what the function returns. This is required.@export - when people install your package, can they use this function
@examples - code to show how the function works. Wrap functions in \dontrun{} if not wanted to runYou can add @title and @description tags:
#' @title #' @description #' #' @param x
…
#' @title Print the top of a matrix
#' @description `top` is a small function to not just present the first rows
#' of a matrix, but also the first number of columns
#'
#' @param x a `matrix`
#' @param n Number of rows and columns to display of the matrix,
#' similar to [utils::head()]
#'
#' @returns The matrix that is subset based on parameters
#' @export
#'
#' @examples
#' mat = matrix(rnorm(100), nrow = 10)
#' top(mat, n = 4)
#' \dontrun{
#' top(mat, n = 10)
#' }
NULL and use is.null() to test#' @rdname.#' @inheritParams for different functions with the same arguments.verbose argument for printingmessage (not cat) for printing. Someone can use suppressMessages to stop the printing. Wrap these with if (verbose)... to a main function for additional options for the user.usethis::use_vignette()do.call(FUNCTION, args = list_of_arguments)The NAMESPACE files tells the R package what to import and export. In Roxygen:
@export - adds this to the NAMESPACE file
@import - in roxygen, if you want to import a package, you say @import PACKAGENAME
library(PACKAGENAME)@importFrom - in roxygen, if you want to import a function, you say @import PACKAGENAME func1 func2
pkgA has function dothing and pkgB has functions dothing and other, if @import pkgA dothing, @import pkgB other, then if you call dothing(), R knows it’s from pkgAbase package, includying anything from stats (e.g. quantile) or graphics (e.g. hist)Add @importFrom graphics hist to your top.R file
Typically: create imports.R because you only need to import stuff in one place. Keeping in multiple places is hard to track.
For every function you’re using from a package, use package::function()
@import or @importFrom tagdplyr), so you can use importIf using magrittr::%>%, run:
usethis::use_pipe()
Creates help file for an overview of your package (not many read it in my experience).
usethis::use_package_doc()
The data-raw directory can be data you want to create (such as simulated data).
This will have scripts with use_data at the end to make the data (next slide)
usethis::usethis::use_data_raw()
The data/ directory is where data goes, it must be named .RData or rda. The use_data function can do this for you:
usethis::use_data(DATAOBJECT, compress = "xz")
The output will be DATAOBJECT.rda in the data folder. You can use this in your package
Note how DATAOBJECT is the name of the object/rda. Now we can document the data as follows:
#' @title Some object to document
#'
#' @description A list containing things
#'
#' @format A list with 7 elements, which are:
#' \describe{
#' \item{x}{first thing}
#' \item{y}{second thing}
#' }
"DATAOBJECT"
The inst/ directory will copy any of the contents to the installed directory path. So if blah.csv was in inst/ then it will be in the directory.
Most times, however, people put data in inst/extdata to separate folders out.
You can use find.package to find the installed directory:
find.package("readr")
## [1] "/Library/Frameworks/R.framework/Versions/4.4-x86_64/Resources/library/readr"
To get files, though, you should use system.file:
system.file("extdata", package = "readr")
## [1] "/Library/Frameworks/R.framework/Versions/4.4-x86_64/Resources/library/readr/extdata"
If you pass in multiple characters, it assumes you put it together with file.path:
system.file("extdata", "challenge.csv", package = "readr")
## [1] "/Library/Frameworks/R.framework/Versions/4.4-x86_64/Resources/library/readr/extdata/challenge.csv"
The mustWork argument is useful for making sure the file exists:
system.file("extdata", "asdfsdf.csv", package = "readr", mustWork = TRUE)
## Error in system.file("extdata", "asdfsdf.csv", package = "readr", mustWork = TRUE): no file found
file.path > paste for paths (or fs package)file.exists. Use any and allfile.remove if you need to delete thingstempfile(fileext = ".csv").dir.create to create and unlink to destroy directories.tempdir() for stuff that’s intermediate.tdir = tempfile(); dir.create(tdir); on.exit({ unlink(tdir) })file.copy and file.renamedownload.file or curl::curl_downloadA package has data + code + dependencies. A vignette can tie this together to tell you how to use the package. Typically it is an analysis.
usethis::use_vignette("my-vignette")
The testthat package is great for unit testing. Put test scripts in tests/testthat, always named test-DESCRIPTOR.R. To set up testthat:
usethis::use_testthat()
And a specific test:
usethis::use_test("name of test")
The testthat package is great for unit testing. Put test scripts in tests/testthat, always named test-DESCRIPTOR.R. To set up testthat:
testthat::context("OVERALL DESCRIPTION OF TESTS IN THIS FILE")
testthat::test_that("Description of this test", { MYCODE })
testthat::expect_equal(OUTPUT, 1234.34535)
testthat::expect_identcal(OUTPUT1, OUTPUT2)
testthat::expect_true(SOME_OUTPUT)
testthat::expect_silent({ no_warning_error_code })
testthat::expect_message({ some_warn }, "a[test]regexp")
Use covr package:
covr::package_coverage() # run tests
covr::report() # get a report
covr::report(covr::package_coverage(type = "all")) # run them all
usethis::use_github_action("test-coverage") # test it on GitHub, put CODECOV_TOKEN in SECRET
devtools::spell_check() devtools::check_win_devel() devtools::show_news() usethis::use_cran_comments() devtools::release() # do this if to be sure devtools::submit_cran() # use only if you know what you're doing
pkgdownWant a site that has nice documentation: enter pkgdown!
usethis::use_pkgdown()
usethis::use_github_action("pkgdown")
usethis::use_pkgdown_github_pages() #
README is your index.html
Vignettes are in Articles
“But does it work on someone else’s machine or just mine?”
Continuous Integration (CI) is a development practice that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early.
usethis::use_git() # make a Git repo
usethis::use_github() # must have GITHUB_PAT set up
usethis::use_github(protocol = "https") # must have GITHUB_PAT set up
usethis::use_readme_rmd() # make a readme
usethis::use_github_action("check-standard")
https://github.com/r-lib/actions
usethis::use_github_action("check-standard")
.github/workflows/README.RmdThese function adds following lines, changing GITHUB_USERNAME/REPO to the correct version
[](https://github.com/GITHUB_USERNAME/REPO/actions)
or a general badge:
usethis::use_badge("Travis-CI Build Status",
src = "https://travis-ci.com/GITHUB_USERNAME/REPO.svg?branch=master",
href = "https://travis-ci.com/GITHUB_USERNAME/REPO")
to the README.Rmd.
class(x) = "myS3Class"
new
class$method()bar <- function(y) UseMethod("bar", y)
bar.myS3Class will allow you to use bar(x)setGeneric("myGeneric", function(x) standardGeneric("myGeneric"))setMethod("myGeneric", signature(x = "myS3Class"), function(x, y) {
x@slot + y
})
See http://r-pkgs.had.co.nz/src.html
src/ folder has compiled code.cleanup generally deletes intermediate or downloaded files run in configure.configure runs code before make is runMakevars or a Makefile gives direction for compiling codeconfigure.win and Makevars.win for Windows-specific setup..Call for calling these compiled functions.Using Rcpp is a different framework.