class: center, middle, inverse, title-slide # R Packages ##
Statistical Programming ### Fall 2021 ###
Dr. Colin Rundel --- exclude: true --- ## What are R packages? R packages are just a collection of files (R code, compiled code, data, documentation, etc.) that live in your library path. -- ```r .libPaths() ``` ``` ## [1] "/usr/local/lib/R/4.1/site-library" "/usr/local/Cellar/r/4.1.2/lib/R/library" ``` -- When you run `library(pkg)` the functions (and objects) in the package's namespace are attached to the global search path. ```r dir(.libPaths()) ``` ``` ## [1] "abind" "airports" "archive" "arrayhelpers" "AsioHeaders" ## [6] "askpass" "assertthat" "av" "available" "backports" ## [11] "base" "base64enc" "BayesFactor" "bayesplot" "beeswarm" ## [16] "bench" "benchmarkme" "benchmarkmeData" "BH" "bit" ## [21] "bit64" "blob" "bookdown" "boot" "branchMover" ## [26] "brew" "brio" "broom" "broom.mixed" "bslib" ## [31] "cachem" "callr" "cellranger" "checklist" "checkmate" ## [36] "cherryblossom" "chromote" "chron" "class" "classInt" ## [41] "cli" "clipr" "clisymbols" "cluster" "cmdstanr" ## [46] "coda" "codetools" "collections" "colorblindr" "colorspace" ## [51] "colourpicker" "commonmark" "compiler" "config" "conflicted" ## [56] "contfrac" "countdown" "cowplot" "cpp11" "crayon" ## [61] "credentials" "crosstalk" "cubature" "curl" "cyclocomp" ## [66] "DAAG" "data.table" "datasauRus" "datasets" "DBI" ## [71] "dbplyr" "desc" "deSolve" "devtools" "dials" ## [76] "DiceDesign" "diffmatchpatch" "diffobj" "digest" "distributional" ## [81] "doMC" "doParallel" "dotCall64" "downlit" "dplyr" ## [86] "DT" "dtplyr" "dygraphs" "e1071" "ellipsis" ## [91] "elliptic" "emo" "evaluate" "fansi" "farver" ## [96] "fastmap" "fields" "fizzbuzz" "FNN" "fontawesome" ## [101] "forcats" "foreach" "foreign" "fs" "furrr" ## [106] "future" "future.apply" "gargle" "generics" "geojsonsf" ## [111] "geometries" "geosphere" "gert" "GGally" "gganimate" ## [116] "ggbeeswarm" "ggdist" "gghighlight" "ggplot2" "ggrepel" ## [121] "ggridges" "ggthemes" "gh" "ghclass" "gifski" ## [126] "gitcreds" "glmnet" "globals" "glue" "googledrive" ## [131] "googlesheets4" "gower" "GPfit" "graphics" "grDevices" ## [136] "grid" "gridExtra" "gsubfn" "gtable" "gtools" ## [141] "hardhat" "haven" "HDInterval" "here" "highlite" ## [146] "highr" "hms" "htmltools" "htmlwidgets" "httpuv" ## [151] "httr" "httr2" "hunspell" "hypergeo" "ids" ## [156] "igraph" "infer" "ini" "inline" "ipred" ## [161] "isoband" "iterators" "janeaustenr" "janitor" "jpeg" ## [166] "jquerylib" "jsonify" "jsonlite" "kableExtra" "katex" ## [171] "keras" "kernlab" "KernSmooth" "knitr" "ks" ## [176] "labeling" "languageserver" "later" "lattice" "latticeExtra" ## [181] "lava" "lazyeval" "leafem" "leaflet" "leaflet.providers" ## [186] "leafpop" "learnr" "learnrhash" "lhs" "lifecycle" ## [191] "lintr" "listenv" "lme4" "lobstr" "loo" ## [196] "lookup" "lubridate" "lwgeom" "magick" "magrittr" ## [201] "maps" "maptools" "mapview" "markdown" "MASS" ## [206] "Matrix" "MatrixModels" "matrixStats" "mclust" "md4r" ## [211] "memoise" "methods" "mgcv" "mime" "miniUI" ## [216] "minqa" "misc3d" "modeldata" "modelr" "multicool" ## [221] "munsell" "mvtnorm" "nlme" "nloptr" "nnet" ## [226] "numDeriv" "nycflights13" "openintro" "openssl" "oskeyring" ## [231] "packrat" "pagedown" "palmerpenguins" "parallel" "parallelly" ## [236] "parsedate" "parsermd" "parsnip" "patchwork" "pbapply" ## [241] "pillar" "pkgbuild" "pkgconfig" "pkgdown" "pkgload" ## [246] "plogr" "plot3D" "plotrix" "plyr" "png" ## [251] "polite" "posterior" "pracma" "praise" "prettyunits" ## [256] "pROC" "processx" "prodlim" "profmem" "profvis" ## [261] "progress" "progressr" "promises" "proto" "proxy" ## [266] "pryr" "ps" "purrr" "queryparser" "R.cache" ## [271] "R.methodsS3" "R.oo" "R.utils" "R6" "ragg" ## [276] "randomNames" "ranger" "RANN" "rapidjsonr" "rappdirs" ## [281] "raster" "ratelimitr" "rcmdcheck" "RColorBrewer" "Rcpp" ## [286] "RcppEigen" "RcppParallel" "reactable" "reactR" "readr" ## [291] "readxl" "recipes" "rematch" "rematch2" "remotes" ## [296] "renv" "reprex" "repurrrsive" "reshape" "reshape2" ## [301] "reticulate" "rex" "rgdal" "rgeos" "RhpcBLASctl" ## [306] "rhub" "rjags" "rlang" "rmarkdown" "RMySQL" ## [311] "robotstxt" "roxygen2" "rpart" "rprojroot" "rsample" ## [316] "rsconnect" "RSQLite" "rstan" "rstanarm" "rstantools" ## [321] "rstudioapi" "rticles" "RUnit" "rversions" "rvest" ## [326] "s2" "sass" "satellite" "scales" "selectr" ## [331] "servr" "sessioninfo" "sf" "sfheaders" "shape" ## [336] "shiny" "shinycssloaders" "shinyFiles" "shinyjs" "shinystan" ## [341] "shinythemes" "signal" "slider" "sloop" "snakecase" ## [346] "SnowballC" "sodium" "sourcetools" "sp" "spam" ## [351] "spatial" "spiderbar" "splines" "sqldf" "SQUAREM" ## [356] "StanHeaders" "stats" "stats4" "statsr" "stringdist" ## [361] "stringi" "stringr" "styler" "survival" "svglite" ## [366] "svUnit" "sys" "systemfonts" "tcltk" "tensorA" ## [371] "tensorflow" "terra" "testthat" "textshaping" "textutils" ## [376] "tfautograph" "tfruns" "threejs" "tibble" "tidybayes" ## [381] "tidymodels" "tidyquery" "tidyr" "tidyselect" "tidytext" ## [386] "tidyverse" "timeDate" "tinytex" "tokenizers" "tools" ## [391] "toOrdinal" "trajr" "transcodeR" "translations" "truncnorm" ## [396] "tune" "tweenr" "tzdb" "udapi" "units" ## [401] "unvotes" "usdata" "usethis" "utf8" "utils" ## [406] "uuid" "V8" "vctrs" "vipor" "viridis" ## [411] "viridisLite" "vroom" "waldo" "warp" "webshot" ## [416] "websocket" "whisker" "whoami" "withr" "wk" ## [421] "workflows" "workflowsets" "xaringan" "xaringanBuilder" "xaringanthemer" ## [426] "xfun" "xml2" "xmlparsedata" "xopen" "xtable" ## [431] "xts" "yaml" "yardstick" "yesno" "zeallot" ## [436] "zip" "zoo" ``` --- ## Search path ```r search() ``` ``` ## [1] ".GlobalEnv" "package:stats" "package:graphics" "package:grDevices" "package:utils" ## [6] "package:datasets" "package:methods" "Autoloads" "package:base" ``` -- ```r library(diffmatchpatch) ``` -- ```r search() ``` ``` ## [1] ".GlobalEnv" "package:diffmatchpatch" "package:stats" "package:graphics" ## [5] "package:grDevices" "package:utils" "package:datasets" "package:methods" ## [9] "Autoloads" "package:base" ``` --- ## Loading vs attaching If you do not want to attach a package you can directly use functions via `::` or load it with `requireNamespace()`. .small[ ```r loadedNamespaces() ``` ``` ## [1] "Rcpp" "grDevices" "digest" "diffmatchpatch" "R6" "jsonlite" ## [7] "magrittr" "evaluate" "datasets" "xaringan" "stringi" "rlang" ## [13] "utils" "jquerylib" "bslib" "graphics" "rmarkdown" "base" ## [19] "tools" "stringr" "xfun" "yaml" "fastmap" "compiler" ## [25] "stats" "htmltools" "knitr" "methods" "sass" ``` ] -- .small[ ```r requireNamespace("forcats") ``` ``` ## Loading required namespace: forcats ``` ] -- .small[ ```r loadedNamespaces() ``` ``` ## [1] "Rcpp" "grDevices" "digest" "diffmatchpatch" "R6" "jsonlite" ## [7] "magrittr" "evaluate" "datasets" "xaringan" "stringi" "rlang" ## [13] "utils" "jquerylib" "bslib" "graphics" "rmarkdown" "base" ## [19] "forcats" "tools" "stringr" "xfun" "yaml" "fastmap" ## [25] "compiler" "stats" "htmltools" "knitr" "methods" "sass" ``` ```r search() ``` ``` ## [1] ".GlobalEnv" "package:diffmatchpatch" "package:stats" "package:graphics" ## [5] "package:grDevices" "package:utils" "package:datasets" "package:methods" ## [9] "Autoloads" "package:base" ``` ] --- ## Where to R packages come from We've already seen the two primary sources of R packages: CRAN: ```r install.packages("diffmatchpatch") ``` GitHub: ```r remotes::install_github("rundel/diffmatchpatch") ``` there is one other method that comes up (particularly around package development), which is to install a package from local files. Local install: ```bash R CMD install diffmatchpatch_0.1.0.tar.gz ``` ```r devtools::install("diffmatchpatch_0.1.0.tar.gz") ``` --- ## What is CRAN It is the Comprehensive R Archive Network which is the central repository of R packages. * Maintained by the R Foundation and run by a team of volunteers, ~22k packages * Retains all current versions of released packages as well as archives of previous versions * Similar in spirit to Perl's CPAN, TeX's CTAN, and Python's PyPI * Some important features: * All submissions are reviewed by humans + automated checks * Strictly enforced submission policies and package requiements * All packages must be actively maintained and support upstream and downstream changes .footnote[ See [Writing R Extensions](https://cran.r-project.org/doc/manuals/r-release/R-exts.html) ] --- ## Structure of an R Package <br/> <br/> <img src="imgs/r_pkg_struct.jpeg" width="80%" style="display: block; margin: auto;" /> .footnote[ From [A Quickstart Guide for Building Your First R Package](https://methodsblog.com/2015/11/30/building-your-first-r-package/) ] --- ## Core components * `DESCRIPTION` - file containing package metadata (e.g. package name, description, version, license, and author details). Also specifies package dependencies, * `NAMESPACE` - details which functions and objects are exported by your package * `R/` - folder containing R script files (`.R`) * `man/` - folder containing R documentation files (`.Rd`) -- The following components are optional, but quite common: * `tests/` - folder contain unit tests * `src/` - folder containing code to be compiled (usually C / C++) * `data/` - folder containing example data sets (exported as `.Rdata` via `save()`) * `inst/` - files that will be copied to the package's top-level directory when it is installed (e.g. examples or data files that don't belong in `data/`) * `vignettes/` - file implementing long form documentation, can be static (`.pdf` or `.html`) or literate documents (e.g. `.Rmd` or `.Rnw`) --- ## Package contents .pull-left[ .small[ Source Package ```r fs::dir_tree("~/Desktop/Projects/diffmatchpatch/") ``` ``` ## ~/Desktop/Projects/diffmatchpatch/ ## ├── DESCRIPTION ## ├── LICENSE.md ## ├── NAMESPACE ## ├── NEWS.md ## ├── R ## │ ├── RcppExports.R ## │ ├── diff.R ## │ ├── diffmatchpatch-package.R ## │ ├── match.R ## │ ├── options.R ## │ ├── patch.R ## │ └── print.R ## ├── README.Rmd ## ├── README.md ## ├── cran-comments.md ## ├── diffmatchpatch.Rproj ## ├── inst ## │ └── include ## │ └── diff_match_patch.h ## ├── man ## │ ├── diff.Rd ## │ ├── dmp_options.Rd ## │ ├── match.Rd ## │ └── patch.Rd ## └── src ## ├── Makevars ## ├── Makevars.win ## ├── RcppExports.cpp ## ├── RcppExports.o ## ├── common.h ## ├── diff.cpp ## ├── diff.o ## ├── diffmatchpatch.so ## ├── match.cpp ## ├── match.o ## ├── options.cpp ## ├── options.o ## ├── patch.cpp ## └── patch.o ``` ] ] .pull-right[ .small[ Installed Package ```r fs::dir_tree(system.file(package="diffmatchpatch")) ``` ``` ## /usr/local/lib/R/4.1/site-library/diffmatchpatch ## ├── DESCRIPTION ## ├── INDEX ## ├── Meta ## │ ├── Rd.rds ## │ ├── features.rds ## │ ├── hsearch.rds ## │ ├── links.rds ## │ ├── nsInfo.rds ## │ └── package.rds ## ├── NAMESPACE ## ├── NEWS.md ## ├── R ## │ ├── diffmatchpatch ## │ ├── diffmatchpatch.rdb ## │ └── diffmatchpatch.rdx ## ├── help ## │ ├── AnIndex ## │ ├── aliases.rds ## │ ├── diffmatchpatch.rdb ## │ ├── diffmatchpatch.rdx ## │ └── paths.rds ## ├── html ## │ ├── 00Index.html ## │ └── R.css ## ├── include ## │ └── diff_match_patch.h ## └── libs ## └── diffmatchpatch.so ``` ] ] --- class: center, middle ## A deeper dive on [diffmatchpatch](https://github.com/rundel/diffmatchpatch) --- ## Package Installation <img src="imgs/r_pkg_install.png" width="80%" style="display: block; margin: auto;" /> .footnote[ From [R Packages - Chap. 4](https://r-pkgs.org/package-structure-state.html#installed-package) ] --- ## Package Installion - Files <img src="imgs/r_pkgs_fig.png" width="55%" style="display: block; margin: auto;" /> .footnote[ From [R Packages - Chap. 4.5](https://r-pkgs.org/package-structure-state.html#bundled-package) ] --- ## Package development What follows is an *opinionated* introduction to package development, * this is not the only way to do thing (none of the following are required) * I would strongly recommend using: * RStudio * RStudio projects * GitHub * usethis * roxygen2 --- class: center, middle <img src="imgs/hex_usethis.png" width="45%" style="display: block; margin: auto;" /> --- ## `usethis` This is an immensely useful package for automating all kinds of routine (and tedious) tasks within R * Tools for managing git and GitHub configuration * Tools for managing collaboration on GitHub via pull requests (see `pr_*()`) * Tools for creating and configuring packages * Tools for configuring your R environment (e.g. `.Rprofile` and `.Renviron`) * and much much more --- class: center, middle ## Live demo - Building a Package