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 available::available
function:
available::available("ggplot")
## ── ggplot ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ## Name valid: ✔ ## Available on CRAN: ✖ ## Available on Bioconductor: ✔ ## Available on GitHub: ✖ ## Abbreviations: http://www.abbreviations.com/ggplot ## Wikipedia: https://en.wikipedia.org/wiki/ggplot ## Wiktionary: https://en.wiktionary.org/wiki/ggplot ## Sentiment:???
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_*_license
I add this to the DESCRIPTION
file:
Authors@R: c(person(given = "John", family = "Muschelli", email = "muschellij2@gmail.com", 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 pkgA
base
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 import
If 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 all
file.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.rename
download.file
or curl::curl_download
A 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
pkgdown
Want 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.Rmd
These 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.