for other options) \n\n1: check-standard: Run `R CMD check` on Linux, macOS, and Windows\n2: test-coverage: Compute test coverage and report to https://about.codecov.io\n3: pr-commands: Add /document and /style commands for pull requests\n```\n\n`check-standard` sets up a GHA that runs `R CMD check` with the latest release of R on Linux, Mac, and Windows and with both the previous release and development release of R on Linux.\n\n::: {.notes}\nThis behaviour of `use_github_action()` is new in usethis 2.2.\n\n`use_github_actions()` is deprecated.\n:::\n\n## [`use_github_action(\"check-release\")`]{.smaller90}\n\nThe `check-standard` GHA is best-practice for 'serious' projects, e.g. those aiming for CRAN, but is overkill for our purposes. \n\nWe can set up a simpler GHA by specifying an alternative:\n\n```{.r}\nuse_github_action(\"check-release\")\n```\n\nThis sets up a bare-minimum workflow that runs `R CMD check` with the latest release of R on Linux.\n\nIt's good for simple package with no OS-sepcific code, and if you want a quick start with R CI.\n\n::: {.notes}\ni.e. it's perfect for us! \n\nReminder to fix any issues as soon as they arise!\n:::\n\n## Your turn\n\n1. Create a README for `animalsounds` with `usethis::use_readme_rmd()`.\n2. Fill in the description and an example.\n3. Try adding the README in a git commit -- it should fail! Render the README with `build_readme()`, then add both `README.Rmd` and `README.md` in a git commit.\n4. Run `usethis::use_github_action(\"check-release\")`. It adds a badge to the README, so you will need to render the README again.\n5. Commit all the changes to git.\n\n# Vignettes {.inverse}\n\n## Vignettes\n\nVignettes are long-form documentation for your package.\n\nThey use R markdown to integrate code and output into the documentation. Typically:\n\n - A single/main vignette showing a complete workflow. \n - Optional further vignette(s) going deeper on one aspect/application\n - Optional further vignette(s) for specialist audience (methodologists or developers)\n \nA vignette with the same name as the package (e.g., `vignettes/animalsounds.Rmd` or `vignettes/articles/animalsounds.Rmd`) automatically becomes a top-level \"Get started\" link.\n \n::: {.notes}\nFairly short read ~10 minutes\n::: \n\n## `use_vignette()`\n\nEasiest way to get started is with `usethis::use_vignette()`\n\n```r\nusethis::use_vignette(\"name\")\n```\n\nAdds to DESCRIPTION\n\n\nSuggests: knitr\nVignetteBuilder: knitr\n
\n\nCreates `vignettes/`\n\nDrafts `vignettes/name.Rmd`\n\n::: {.notes}\nuse_vignette() will fill both title fields with the \"name\" of the file, but you'll want to edit to something more descriptive.\n\nNeeds to be .Rmd not .qmd. Quarto is not R-specific and CRAN can't publish .qmd files. \n:::\n\n## Vignette = Rmarkdown + special metadata\n\n```\n---\ntitle: \"Vignette Title\"\nauthor: \"Vignette author\"\ndate: \"2025-11-17\"\noutput: rmarkdown::html_vignette\nvignette: >\n%\\VignetteIndexEntry{Vignette Title}\n%\\VignetteEngine{knitr::rmarkdown}\n%\\VignetteEncoding{UTF-8}\n---\n\n```\n* `html_vignette` output uses a custom style sheet to keep the file size of the \nHTML as small as possible.\n* The `vignette:` field contains special metadata needed when the package is \nbuilt. **Don't forget to change the title here too!**\n\n## Vignette workflow\n\n{fig-align=\"center\"}\n\n::: {.notes}\nNeed to install package so can call with `library()` \n:::\n\n## Articles\n\nVignette code needs to be able to run on CRAN. There are some cases where [this is not possible](https://r-pkgs.org/vignettes.html#sec-vignettes-eval-option).\n\nAs an alternative, you can use articles instead of vignettes:\n\n```{.r}\nusethis::use_article(\"my-article\")\n```\n\n```\n✔ Adding 'rmarkdown' to Config/Needs/website\n✔ Creating 'vignettes/'\n✔ Creating 'vignettes/articles/'\n✔ Adding '*.html', '*.R' to 'vignettes/.gitignore'\n✔ Writing 'vignettes/articles/my-article.Rmd'\n• Modify 'vignettes/articles/my-article.Rmd'\n✔ Adding '^vignettes/articles$' to '.Rbuildignore'\n```\n\n## Your turn\n\n1. Install your **animalsounds** package and restart R (Install button).\n2. Create a simple vignette, `animalsounds`, that shows how to use `animal_sounds()`.\n3. Fix the \"vignette title\" in the YAML header.\n4. Knit the vignette to preview it.\n5. Run `devtools::install(build_vignettes = TRUE)` to install the package with the vignettes. Call `browseVignettes(\"animalsounds\")` to open your vignette.\n6. Commit your changes to git.\n\n# NEWS {.inverse}\n\n## Track changes in a NEWS file\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\nusethis::use_news_md()\n```\n:::\n\n\nAdd news for the latest version at the top.\n\nUse a top-level heading for each release version\n\n```r\n# animalsounds 1.0.0\n```\n\n\n## What news to include\n\nAdd each change in a bulleted list:\n\n- If you have many changes, split into subsections (e.g.\n `## Major changes`, `## Minor improvements`, `## Bug fixes`).\n- Wait until release to decide if subsections are necessary\n \nNote connections to GitHub:\n\n - If related to a GitHub issue, add the issue number, e.g. (`#10`). \n - If related to a pull request, add the pull request number and the author, e.g. (`#101, @hadley`). \n\n# Package website with pkgdown {.inverse}\n\n## A package website pkgdown\n\nThe **pkgdown** package is designed to make it quick and easy to build a website for your package:\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\nusethis::use_pkgdown()\n```\n:::\n\n\nWhy have a website for your package?\n\n - Google-ability\n - Easy-to-read and browse documentation and package information in one place\n - Examples with output!\n \n## Build a website\n\n`pkgdown::build_site()` creates a package website based on the \nstandard documentation files.\n\n**Home page**: based on README\n\n**Reference**: \n\n - one page for each help file\n - generates an index page, with functions listed alphabetically by default \n \n::: {.notes}\nFor packages with lots of functions, it's good to organise them by theme or functionality.\n:::\n\n## Build a website (ctd)\n\n**Articles**: one page for each vignette\n\n**Get Started**: if you have a vignette with filename = package name\n\n**News**: based on NEWS.md\n\nPlus:\n\n - A link to your GitHub repo (if listed in the DESCRIPTION url field).\n - A link to the License\n - Any badges added to your README (e.g. from GitHub Actions)\n\n## Hosting your website\n\n- You can host your website directly from its GitHub repo (repo has to be public) \n- The recommended approach is to let GitHub build your page (instead of calling `pkgdown::build_site()` and committing and pushing the artifacts of the built website (i.e., html files) to GitHub\n- Add an action to your GitHub repo to be run automatically every time you push to it to rebuild the site:\n\n ```{.r}\n usethis::use_pkgdown_github_pages()\n ```\n\n- The URL will be https://USERNAME.github.io/animalsounds \n \n::: {.notes}\nuse_pkgdown_github_pages() will:\n\n - call `use_pkgdown()` - allow it to overwrite existing `_pkgdown.yml` (will add the url)\n - set up a `gh-pages` branch from which to deploy the site\n - add a `pkgdown.yml` to .github/workflows\n\nWill still need to call `pkgdown::build_site()` to preview locally\n:::\n\n## Customising your website\n\nYou can add more information to `_pkgdown.yml` to customise the package website:\n\n- curate the index for the Reference page - functions can be grouped and described in categories\n\n \n\n- customise the appearance\n\n \n\n## Your turn\n\n1. Run `usethis::use_pkgdown_github_pages()` -- this will ask you to install **pkgdown** if you don't already have it.\n2. Read through all the output in the console to see the many things that this function does. \n3. Look at the diffs in the Git pane. Commit and push all changes.\n4. Go to your GitHub repo of the package. Click on **Actions**. If there's a green tick next to \"pages build and deployment\" then your site is ready to view!\n5. Click on the link to the website under the **About** section of the repo.\n6. (Bonus) Change the appearance of the site with a Bootswatch theme: . \n\n# End matter {.inverse}\n\n## References\n\nWickham, H and Bryan, J, *R Packages* (2nd edn, in progress), .\n\nR Core Team, *Writing R Extensions*, \n\n## License\n\nLicensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License ([CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/){target=\"_blank\"}).\n\n",
+ "markdown": "---\ntitle: Package check and documentation\nsubtitle: R package development workshop
Module 4\nauthor: Forwards teaching team\nformat: forwardspres-revealjs\n---\n\n## Overview\n\n- Check your package!\n- DESCRIPTION\n- README\n- Continuous Integration (CI)\n- Vignettes\n- NEWS\n- Package website with pkgdown \n\n# Check your package! {.inverse}\n\n## R CMD check\n\n`R CMD check` is the command line utility provided by R to check R packages.\n\nIt checks that all the components are valid and consistent with each other, in particular:\n\n- Metadata in DESCRIPTION\n- Imports and exports in NAMESPACE\n- `.Rd` files in `/man`\n\nIt will also run any examples and tests you have written.\n\n`devtools::check()` will run `R CMD check` in the background, with the results shown in the Build pane.\n\n::: notes\nNote that this doesn't check the correctness of code - this is the role of tests\n:::\n\n## Run `devtools::check()`\n\nYou will get lots of output. It will end with:\n\n``` \n-- R CMD check results ---------- animalsounds 0.0.0.9000 ----\nDuration: 9.3s\n\n> checking DESCRIPTION meta-information ... WARNING\n Non-standard license specification:\n `use_mit_license()`, `use_gpl3_license()` or friends to pick a\n license\n Standardizable: FALSE\n\n0 errors √ | 1 warnings x | 0 notes √\n```\n\nWe haven't yet specified a license for our package.\n\n::: notes\nOn running `check()` you may get an error if you are using a networked drive. There's a fix coming in a few slides.\n:::\n\n## A function that fails many checks\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\n#' Make an excited animal sound\n#'\n#' Repeat an animal sound in uppercase.\n#'\n#' @param sound A character string containing an animal sound.\n#' @param times Number of times to repeat the sound.\n#'\n#' @return A character vector.\n#'\n#' @examples\n#' excited_sound(\"moo\", 3)\n#'\n#' @export\nexcited_sound <- function(animal, sound, times = 3) {\n\n sound <- str_to_upper(sound)\n\n paste(\"The\", animal, \"says\", paste(rep(sound, times), collapse = \" \"))\n}\n```\n:::\n\n\n## A function that fails many checks (cont.)\n\n```r\n❯ checking examples ... ERROR\n Running examples in 'animalsounds-Ex.R' failed\n The error most likely occurred in:\n \n > base::assign(\".ptime\", proc.time(), pos = \"CheckExEnv\")\n > ### Name: excited_sound\n > ### Title: Make an excited animal sound\n > ### Aliases: excited_sound\n > \n > ### ** Examples\n > \n > excited_sound(\"moo\", 3)\n Error in str_to_upper(sound) : could not find function \"str_to_upper\"\n Calls: excited_sound\n Execution halted\n\n❯ checking Rd \\usage sections ... WARNING\n Undocumented arguments in Rd file 'excited_sound.Rd'\n 'animal'\n \n Functions with \\usage entries need to have the appropriate \\alias\n entries, and all their arguments documented.\n The \\usage entries must correspond to syntactically valid R code.\n See chapter 'Writing R documentation files' in the 'Writing R\n Extensions' manual.\n\n❯ checking R code for possible problems ... NOTE\n excited_sound: no visible global function definition for 'str_to_upper'\n Undefined global functions or variables:\n str_to_upper\n\n1 error ✖ | 1 warning ✖ | 1 note ✖\nError: R CMD check found ERRORs\nExecution halted\n\nExited with status 1.\n```\n\n## Types of problem\n\n
\n\n| | |\n|-------------|-----------------------------------------------|\n| **ERROR** | Must fix to get the code/example/test working |\n| **WARNING** | Fix if sharing with others |\n| **NOTE** | Fix if submitting to CRAN |\n\n
\n\nIt is possible to submit to CRAN with a NOTE, but it's best avoided.\n\n::: notes\nNOTES best avoid for CRAN as they require a person to respond. One unavoidable case of a NOTE on CRAN submission: first submission of a package\n:::\n\n## Check regularly, fix issues as they arise {.inverse .center .center-h}\n\n::: {.notes}\nWill see later in this session how to do this automatically with Continuous Integration \n:::\n\n# DESCRIPTION {.inverse}\n\n::: {.notes}\nThe are two types of documentation: package level and function level.\n\nThe DESCRIPTION file provides some of the package level documentation (or metadata)\n:::\n\n## Metadata in `DESCRIPTION`\n\n- **Package**: The package name. The `changer` package can help you change the name!\n- **Title**: One line, title case, with no period. Fewer than 65 characters.\n- **Version**\n - for release: MAJOR.MINOR.PATCH version.\n - for development version building on version MAJOR.MINOR.PATCH, use: MAJOR.MINOR.PATCH.9000\n - can be filled in with `usethis::use_version()`\n\n## Notes of version number\n\nGiven a version number MAJOR.MINOR.PATCH, increment the:\n\n- MAJOR version when you make incompatible API changes,\n- MINOR version when you add functionality in a backwards compatible manner, and\n- PATCH version when you make backwards compatible bug fixes.\n\nSee for further guidance on when to bump which part of the version number\n\n \n## Metadata in `DESCRIPTION`\n\n:::{.smaller90}\n- **Authors@R**: A call to `person()` that is run to create the Author field when the package tarball is built. \"aut\" means author, \"cre\" means creator (maintainer), \"ctb\" means contributor. \n\n A placeholder call to `person()` is inserted in `DESCRIPTION` when a package is created with `usethis::create_package()` which can be edited directly:\n\n\n ::: {.cell layout-align=\"center\"}\n \n ```{.r .cell-code}\n person(\"A\", \"Person\", email = \"a.person@email.com\", \n role = c(\"aut\", \"cre\"),\n comment = c(ORCID = \"0000-0001-2345-6789\"))\n ```\n :::\n\n\n Alternatively, this can be overwritten with a call to `usethis::use_author()`:\n \n\n ::: {.cell layout-align=\"center\"}\n \n ```{.r .cell-code}\n use_author(\"A\", \"Person\", email = \"a.person@email.com\", \n role = c(\"aut\", \"cre\"),\n comment = c(ORCID = \"0000-0001-2345-6789\"))\n ```\n :::\n\n:::\n\n::: {.notes}\nusethis::use_author() is new in usethis 2.2.0\n:::\n\n## Metadata in `DESCRIPTION`\n\n- **Description**: One paragraph describing what the package does. Keep the width of the paragraph to 80 characters; indent subsequent lines with 4 spaces.\n- **License**: Will discuss later\n- **Encoding**: How to encode text, use UTF-8 encoding.\n- **LazyData**: If `true` data sets in the package are stored in a database during package installation and loaded from the database as required. Recommended if shipping data with package -- `usethis::use_data()` will set this for you.\n\n::: {.notes}\nusethis::create_package() sets UTF-8 encoding\n\nlazy loading means that data is only loaded if needed.\nThis means that they won’t occupy any memory until you use them.\ndo NOT include LazyData: true in DESCRIPTION unless you actually ship data in your package. \n:::\n\n## Open source licenses\n\nThere are three main open source licenses:\n\n- CC0: “public domain”, best for data packages.\n\n\n ::: {.cell layout-align=\"center\"}\n \n ```{.r .cell-code}\n usethis::use_cc0_license()\n ```\n :::\n\n- MIT: Free for anyone to do anything with (including bundling in closed source product).\n\n\n ::: {.cell layout-align=\"center\"}\n \n ```{.r .cell-code}\n usethis::use_mit_license()\n ```\n :::\n\n- GPL: Changes and bundles must also be GPL\n\n ::: {.cell layout-align=\"center\"}\n \n ```{.r .cell-code}\n usethis::use_gpl_license()\n ```\n :::\n\n [If you are including someone else's GPL code directly, you must use GPL yourself.]{.smaller80}\n\n::: {.notes}\nhttps://bookdown.org/rdpeng/RProgDA/open-source-licensing.html\n\nsomewhat personal down to how important you consider open source to be and what you are happy with people doing with your code\n\nSuggest academic: GPL; community/other: MIT \n:::\n\n## Proprietary packages\n\nYou can use `usethis::use_proprietary()` to make it clear that your package isn’t open source.\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\nusethis::use_proprietary(copyright_holder = \"ACME Ltd\")\n```\n:::\n\n\nIn DESCRIPTION:\n```\nLicense: file LICENSE\n```\nIn LICENSE:\n```\nCopyright 2023 ACME Ltd. All rights reserved.\n```\n\n## Your turn\n\n1. Open the DESCRIPTION file and add a title and description.\n2. Add yourself as an author and creator.\n3. Add an MIT license.\n4. Run the package check.\n5. Commit changes to GitHub.\n\n:::{.callout-tip}\nIn RStudio, you can use the 'Go to file/function' box or Ctrl + . [period] and start typing a file name to open a file for editing.\n:::\n\n# README {.inverse}\n\n## README\n\nThe README is the quick start guide to your package.\n\nIt should include \n\n - a brief overview\n - instructions on how to install the package\n - a few examples\n \nYou should be able to borrow from the DESCRIPTION and help files!\n\nIt's readable on the package's GitHub repo and on the homepage of its website (more on that later).\n\n## Creating a README\n\n**usethis** has functions to set up a README with/without R code\n\n```r\nusethis::use_readme_rmd()\nusethis::use_readme_md()\n```\n\n`README.Rmd` must be rendered to make `README.md` each time it \nis changed.\n\n`usethis::use_readme_rmd()` creates a _pre-commit hook_ to check if `README.Rmd` and `README.md` are out of sync before committing.\n\nUse `build_readme()` to render with the latest version of the code.\n\n::: {.notes}\n`build_readme` creates a temporary version of the package\n:::\n\n# Continuous Integration (CI) {.inverse}\n\n::: {.notes}\nThe practice of merging new code into the repository and running checks each time is known as Continuous Integration.\n:::\n\n## Running automatic checks\n\nGitHub Actions (GHAs) allow you to run code every time you push to GitHub. \n\nThe most useful ones for packages can be selected from a call to `usethis::use_github_action()`:\n\n```{.r}\nuse_github_action()\n```\n\n```\nWhich action do you want to add? (0 to exit)\n(See for other options) \n\n1: check-standard: Run `R CMD check` on Linux, macOS, and Windows\n2: test-coverage: Compute test coverage and report to https://about.codecov.io\n3: pr-commands: Add /document and /style commands for pull requests\n```\n\n`check-standard` sets up a GHA that runs `R CMD check` with the latest release of R on Linux, Mac, and Windows and with both the previous release and development release of R on Linux.\n\n::: {.notes}\nThis behaviour of `use_github_action()` is new in usethis 2.2.\n\n`use_github_actions()` is deprecated.\n:::\n\n## [`use_github_action(\"check-release\")`]{.smaller90}\n\nThe `check-standard` GHA is best-practice for 'serious' projects, e.g. those aiming for CRAN, but is overkill for our purposes. \n\nWe can set up a simpler GHA by specifying an alternative:\n\n```{.r}\nuse_github_action(\"check-release\")\n```\n\nThis sets up a bare-minimum workflow that runs `R CMD check` with the latest release of R on Linux.\n\nIt's good for simple package with no OS-sepcific code, and if you want a quick start with R CI.\n\n::: {.notes}\ni.e. it's perfect for us! \n\nReminder to fix any issues as soon as they arise!\n:::\n\n## Your turn\n\n1. Create a README for `animalsounds` with `usethis::use_readme_rmd()`.\n2. Fill in the description and an example.\n3. Try adding the README in a git commit -- it should fail! Render the README with `build_readme()`, then add both `README.Rmd` and `README.md` in a git commit.\n4. Run `usethis::use_github_action(\"check-release\")`. It adds a badge to the README, so you will need to render the README again.\n5. Commit all the changes to git.\n\n# Vignettes {.inverse}\n\n## Vignettes\n\nVignettes are long-form documentation for your package.\n\nThey use R markdown to integrate code and output into the documentation. Typically:\n\n - A single/main vignette showing a complete workflow. \n - Optional further vignette(s) going deeper on one aspect/application\n - Optional further vignette(s) for specialist audience (methodologists or developers)\n \nA vignette with the same name as the package (e.g., `vignettes/animalsounds.Rmd` or `vignettes/articles/animalsounds.Rmd`) automatically becomes a top-level \"Get started\" link.\n \n::: {.notes}\nFairly short read ~10 minutes\n::: \n\n## `use_vignette()`\n\nEasiest way to get started is with `usethis::use_vignette()`\n\n```r\nusethis::use_vignette(\"name\")\n```\n\nAdds to DESCRIPTION\n\n\nSuggests: knitr\nVignetteBuilder: knitr\n
\n\nCreates `vignettes/`\n\nDrafts `vignettes/name.Rmd`\n\n::: {.notes}\nuse_vignette() will fill both title fields with the \"name\" of the file, but you'll want to edit to something more descriptive.\n\nNeeds to be .Rmd not .qmd. Quarto is not R-specific and CRAN can't publish .qmd files. \n:::\n\n## Vignette = Rmarkdown + special metadata\n\n```\n---\ntitle: \"Vignette Title\"\nauthor: \"Vignette author\"\ndate: \"2026-06-29\"\noutput: rmarkdown::html_vignette\nvignette: >\n%\\VignetteIndexEntry{Vignette Title}\n%\\VignetteEngine{knitr::rmarkdown}\n%\\VignetteEncoding{UTF-8}\n---\n\n```\n* `html_vignette` output uses a custom style sheet to keep the file size of the \nHTML as small as possible.\n* The `vignette:` field contains special metadata needed when the package is \nbuilt. **Don't forget to change the title here too!**\n\n## Vignette workflow\n\n{fig-align=\"center\"}\n\n::: {.notes}\nNeed to install package so can call with `library()` \n:::\n\n## Articles\n\nVignette code needs to be able to run on CRAN. There are some cases where [this is not possible](https://r-pkgs.org/vignettes.html#sec-vignettes-eval-option).\n\nAs an alternative, you can use articles instead of vignettes:\n\n```{.r}\nusethis::use_article(\"my-article\")\n```\n\n```\n✔ Adding 'rmarkdown' to Config/Needs/website\n✔ Creating 'vignettes/'\n✔ Creating 'vignettes/articles/'\n✔ Adding '*.html', '*.R' to 'vignettes/.gitignore'\n✔ Writing 'vignettes/articles/my-article.Rmd'\n• Modify 'vignettes/articles/my-article.Rmd'\n✔ Adding '^vignettes/articles$' to '.Rbuildignore'\n```\n\n## Your turn\n\n1. Install your **animalsounds** package and restart R (Install button).\n2. Create a simple vignette, `animalsounds`, that shows how to use `animal_sounds()`.\n3. Fix the \"vignette title\" in the YAML header.\n4. Knit the vignette to preview it.\n5. Run `devtools::install(build_vignettes = TRUE)` to install the package with the vignettes. Call `browseVignettes(\"animalsounds\")` to open your vignette.\n6. Commit your changes to git.\n\n# NEWS {.inverse}\n\n## Track changes in a NEWS file\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\nusethis::use_news_md()\n```\n:::\n\n\nAdd news for the latest version at the top.\n\nUse a top-level heading for each release version\n\n```r\n# animalsounds 1.0.0\n```\n\n\n## What news to include\n\nAdd each change in a bulleted list:\n\n- If you have many changes, split into subsections (e.g.\n `## Major changes`, `## Minor improvements`, `## Bug fixes`).\n- Wait until release to decide if subsections are necessary\n \nNote connections to GitHub:\n\n - If related to a GitHub issue, add the issue number, e.g. (`#10`). \n - If related to a pull request, add the pull request number and the author, e.g. (`#101, @hadley`). \n\n# Package website with pkgdown {.inverse}\n\n## A package website pkgdown\n\nThe **pkgdown** package is designed to make it quick and easy to build a website for your package:\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\nusethis::use_pkgdown()\n```\n:::\n\n\nWhy have a website for your package?\n\n - Google-ability\n - Easy-to-read and browse documentation and package information in one place\n - Examples with output!\n \n## Build a website\n\n`pkgdown::build_site()` creates a package website based on the \nstandard documentation files.\n\n**Home page**: based on README\n\n**Reference**: \n\n - one page for each help file\n - generates an index page, with functions listed alphabetically by default \n \n::: {.notes}\nFor packages with lots of functions, it's good to organise them by theme or functionality.\n:::\n\n## Build a website (ctd)\n\n**Articles**: one page for each vignette\n\n**Get Started**: if you have a vignette with filename = package name\n\n**News**: based on NEWS.md\n\nPlus:\n\n - A link to your GitHub repo (if listed in the DESCRIPTION url field).\n - A link to the License\n - Any badges added to your README (e.g. from GitHub Actions)\n\n## Hosting your website\n\n- You can host your website directly from its GitHub repo (repo has to be public) \n- The recommended approach is to let GitHub build your page (instead of calling `pkgdown::build_site()` and committing and pushing the artifacts of the built website (i.e., html files) to GitHub\n- Add an action to your GitHub repo to be run automatically every time you push to it to rebuild the site:\n\n ```{.r}\n usethis::use_pkgdown_github_pages()\n ```\n\n- The URL will be https://USERNAME.github.io/animalsounds \n \n::: {.notes}\nuse_pkgdown_github_pages() will:\n\n - call `use_pkgdown()` - allow it to overwrite existing `_pkgdown.yml` (will add the url)\n - set up a `gh-pages` branch from which to deploy the site\n - add a `pkgdown.yml` to .github/workflows\n\nWill still need to call `pkgdown::build_site()` to preview locally\n:::\n\n## Customising your website\n\nYou can add more information to `_pkgdown.yml` to customise the package website:\n\n- curate the index for the Reference page - functions can be grouped and described in categories\n\n \n\n- customise the appearance\n\n \n\n## Your turn\n\n1. Run `usethis::use_pkgdown_github_pages()` -- this will ask you to install **pkgdown** if you don't already have it.\n2. Read through all the output in the console to see the many things that this function does. \n3. Look at the diffs in the Git pane. Commit and push all changes.\n4. Go to your GitHub repo of the package. Click on **Actions**. If there's a green tick next to \"pages build and deployment\" then your site is ready to view!\n5. Click on the link to the website under the **About** section of the repo.\n6. (Bonus) Change the appearance of the site with a Bootswatch theme: . \n\n# Minute cards {.inverse}\n\n- [Cohort 1](https://tally.so/r/VLbEYy)\n- [Cohort 2](https://tally.so/r/kdJa7e)\n\n# End matter {.inverse}\n\n## References\n\nWickham, H and Bryan, J, *R Packages* (2nd edn, in progress), .\n\nR Core Team, *Writing R Extensions*, \n\n## License\n\nLicensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License ([CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/){target=\"_blank\"}).\n\n# Aside notes {.inverse}\n\n## Aside: in case of error\n\nOn running `devtools::check()` you may get an error of the form\n\n``` \nUpdating animalsounds documentation \nError: The specified file is not readable: path-to\\animalsounds\\NAMESPACE \n```\n\nThis can happen if your repo is on a networked drive.\n\nThis is covered in this [Stackoverflow question](https://stackoverflow.com/questions/40530968/overwriting-namespace-and-rd-with-roxygen2) and can be fixed.\n\n## Aside: a fix for networked drives\n\n1. Save a copy of this file: [fix_for_networked_drives.R](../../R/fix_for_networked_drives.R)\n\n Save it somewhere other than the `animalsounds` directory\n\n2. Open the file from the `animalsounds` project session\n\n3. Run the whole file\n\nYou should now find that `devtools::check()` proceeds normally.\n",
"supporting": [],
"filters": [
"rmarkdown/pagebreak.lua"
diff --git a/_freeze/slides/05-publication-maintenance/index/execute-results/html.json b/_freeze/slides/05-publication-maintenance/index/execute-results/html.json
index 548f536..01e37e0 100644
--- a/_freeze/slides/05-publication-maintenance/index/execute-results/html.json
+++ b/_freeze/slides/05-publication-maintenance/index/execute-results/html.json
@@ -1,8 +1,8 @@
{
- "hash": "4d851e48fb8a9efb3056db59240b3e73",
+ "hash": "d63dbb2a06452250cfb1d2c3d73914cc",
"result": {
"engine": "knitr",
- "markdown": "---\ntitle: Packaging dataPublication and maintenance\nsubtitle: R package development workshop
Module 5\nauthor: Forwards teaching team\nformat: forwardspres-revealjs\n---\n\n## Overview\n\n- Publication\n - GitHub\n - R-Universe\n - CRAN\n- Promotion\n- Maintenance\n- *Workshop admin*\n\n::: {.notes}\nThe packaging data section would more naturally fit earlier in the course, but put here because of how the schedule has panned out. \n:::\n\n# Publication {.inverse}\n\n# GitHub {.inverse}\n\n## Your package is already on GitHub\n\nSince your package is already on GitHub, any R user can install it with\n\n```r\nremotes::install_github(\"USER/REPO\")\n```\n\nIf you want to tag it as a release, make sure there's a `NEWS.md` file then run\n\n```r\nusethis::use_version() # set the release version number\n```\n\nCheck the `NEWS.md` file is up-to-date (`use_version()` will modify it) then \n\n```\nusethis::use_github_release()\n```\n\nThis will bundle the source code as a `zip` and a `tar.gz` and make them available from the **Releases** section of the repo homepage.\n\n::: {.notes}\nSee previous session for details about NEWS.md and `usethis::use_news_md()`\n\nuse_github_release() is also part of the CRAN submission process, towards the end of the `use_release_issue()` to-do list.\n:::\n\n# R-Universe {.inverse}\n\n## R-Universe\n\nWith [R-Universe](https://r-universe.dev/), you can create a personal, CRAN-like repository.\n\nYou're in control of what's published in your R-Universe! \n\nIt is a good way to allow users to easily install packages without going through the rigour of the CRAN submission process.\n\nUseful resources:\n\n- Search the whole R-universe: \n- About the R-universe: \n- R-universe help-page: \n\n::: {.notes}\nA project from rOpenSci \n:::\n\n## Installing a package from an R-universe\n\nBinaries are built for Windows and MacOS, which a user can install using \n`install.packages()`, e.g.\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\n# Install 'warwickplots' from the 'warwick-stats-resources' universe\ninstall.packages('warwickplots', repos = c(\n WSR = 'https://warwick-stats-resources.r-universe.dev',\n CRAN = 'https://cloud.r-project.org')\n)\n```\n:::\n\n\n. . .\n\nAlternatively, you can first set `options(repos)` to enable favourite repositories by default:\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\noptions(repos = c(\n WSR = 'https://warwick-stats-resources.r-universe.dev',\n CRAN = 'https://cloud.r-project.org')\n)\ninstall.packages(\"warwickplots\")\n```\n:::\n\n\n\n::: {.notes}\nGive an aside about the warwickplots package\n\nNote that we need to list CRAN as r-universe packages may have dependencies on CRAN packages.\n\nTo make options persist across sessions, add this code to your .RProfile with `usethis::edit_r_profile()`\n\nCRAN repo is listed because r-universe package may have dependencies on packages on CRAN.\n:::\n\n## Create your R-universe\n\nFollow this rOpenSci guide: [How to create your personal CRAN-like repository on R-universe](https://ropensci.org/blog/2021/06/22/setup-runiverse/). \n\n:::{.smaller80}\nIn a nutshell:\n\n1. Create a repository called `.r-universe.dev` on the GitHub account for `username`, e.g. . The repository must contain a file called [packages.json](https://github.com/maelle/maelle.r-universe.dev/blob/main/packages.json) in the standard format, defining at least the `package` name and git `url` for the packages you want to include, e.g.\n \n ```\n [\n {\n \"package\": \"warwickplots\",\n \"url\": \"https://github.com/Warwick-Stats-Resources/warwickplots\"\n }\n ]\n ```\n\n2. Install the [r-universe app](https://github.com/apps/r-universe/installations/new) on the GitHub account that you want to enable. Choose __enable for all repositories__ when asked.\n:::\n\n::: {.notes}\nStill using `maelle` in places as shorter that Warwick-Stats-Resources! \nAlso, nice to give a shout-out to her and her role in rOpenSci.\n\nCopying the example from the r-universe help page, with the example/links to Maelle, but using the example json from WSR to be consistent with previous slide. \n\nMight be worth pointing out that with actual username, don't need `< >`\n:::\n\n## What happens next\n\n- After a few minutes, your source universe will appear on: `https://github.com/r-universe/`\n\n- The universe automatically starts building the packages from your registry. Once finished, they will appear on `https://.r-universe.dev`\n\n- The universe automatically syncs and builds your package git repos once per hour.\n\n- If you encounter any issues, the actions tab in your source universe may show what is going on, for example: \n\n# CRAN {.inverse}\n\n## Why publish on CRAN?\n\n- Sign of quality\n\n - Code is ready to be used (not a beta version)\n - Basic standards: documented code, running examples, etc\n - Works with current version of R and other packages \n - Commitment of maintainer\n- Discoverability\n- Ease of installation\n- Bioconductor, rOpenSci: even higher standards, code review\n\n## It's an involved process\n\n- Read the official [Checklist for CRAN Submissions](https://cran.r-project.org/web/packages/submission_checklist.html) \nto check requirements beyond the automated checks.\n\n- Read the community-created [Prepare for CRAN](https://github.com/ThinkR-open/prepare-for-cran) checklist.\n\n- Useful functions for additional checks:\n - `goodpractice::gp()`\n - `spelling::spell_check_package()`\n\n## `usethis::use_release_issue()`\n\nThis function will first ask you to select the release version (major, minor, patch) then create and open a to-do list as an issue in the package GitHub repo.\n\nFor a first submission, there are around **22** tasks to complete, split into sections, to follow (more-or-less) in order:\n\n- First release (one-time only)\n- Prepare for release\n- Submit to CRAN\n- Wait for CRAN (things to do after package has been accepted)\n\nFor more details on each, see the [Releasing to CRAN](https://r-pkgs.org/release.html) chapter of the R Packages book.\n\n::: {.notes}\nNumber of tasks may vary depending on what you've already done (e.g. use_news_md will appear on list if you haven't already got a NEWS.md file, but won't if you do.)\n\nSome are clearly optional (e.g. drafting a blog post about the release) but most should be followed.\n\nSome relate to promoting the package, rather than the technicalities of releasing it.\n\nThere are some different items for packages already on CRAN - not covered here - see Release chapter of R Packages for more details\n\nWill catch many common 'gotchas', e.g. Title Case for Title, checking all exported functions have @returns and @examples\n:::\n\n## Run \"as CRAN\" checks\n\n[CRAN policies](https://cran.r-project.org/web/packages/policies.html) state that you must run `R CMD check --as-cran` _on the tarball to be uploaded_ with the current version of R-devel.\n\nFirst make sure the package passes check locally:\n```r\ndevtools::check()\n```\n\nThen allow some extra checks:\n```r\ndevtools::check(remote = TRUE, manual = TRUE)\n```\n\nThen send to CRAN's win-builder to check on R-devel\n```r\ndevtools::check_win_devel()\n```\n\nAlso check on Mac (M1)\n\n```r\ndevtools::check_mac_release()\n```\n\n::: {.notes}\nIt's possible that the way your libraries are set up can mask problems with `check()` on your local machine. For example, it's important that your System Library just comes with base and recommended packages and that all packages that you install go in your user library. Aside: Installing R through `rig` takes care of this for you. \n:::\n\n## R-hub v2\n\n- A new (since April 2024) check system.\n- Works best if the package is on GitHub\n- Works with GitHub Actions\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\n# run once\ninstall.packages(\"rhub\") \nrhub::rhub_setup() # guides through set-up process\nrhub::rhub_doctor() # checks the set-up\n\n# run the checks\nrhub::rhub_check()\n```\n:::\n\n\n\nSee [the r-hub blog post](https://blog.r-hub.io/2024/04/11/rhub2/) for more details\n\n## `cran-comments.md`\n\nWrite submission notes, generating the `cran-comments.md` file with\n```r\nusethis::use_cran_comments()\n```\n```\n\n ## Test environments\n * local OS X install (R-release)\n * win-builder (R-release, R-devel) \n\n ## R CMD check results\n\n 0 errors | 0 warnings | 1 note\n\n * This is a new release.\n```\n\nThere’s always one note for a new submission.\n\n::: {.notes}\nuse_cran_comments() will populate cran-comments.md with the R CMD check results section. \n\nThe test environments section needs to be filled by hand\n:::\n\n## Submit to CRAN\n\n```{.r}\ndevtools::release()\n```\n\nThis asks you questions which you should carefully read and answer.\n\n::: {.notes}\nThe use_release_issue() function uses devtools::submit_cran() rather than devtools::release(), but the documentation page for submit_cran() recommends using release() instead as it performs more checks. \n:::\n\n## If your submission fails\n\nDo not despair! It happens to everyone, even R-core members.\n\nIf it’s from the CRAN robot, just fix the problem & resubmit.\n\nIf it’s from a human, do not respond to the email and do not argue. Instead update `cran-comments.md` & resubmit.\n\n## For resubmission\n\n```\n This is a resubmission. Compared to the last submission, I\n have:\n\n * First change.\n * Second change.\n * Third change.\n\n --\n\n ## Test environments\n * local OS X install, R 3.2.2\n * win-builder (devel and release)\n\n ## R CMD check results\n ...\n```\n\n## Subsequent submissions to CRAN\n\nProceed as before. If you have reverse dependencies you need to also run \n`R CMD check` on them, and notify CRAN if you have deliberately broken them.\n\nFortunately the **revdepcheck** package makes this fairly easy\n\n```r\nremotes::install_github(\"r-lib/revdepcheck\")\nusethis::use_revdep()\n\nrevdepcheck::revdep_check()\nrevdepcheck::revdep_report_cran() # get intermediate report for cran \n```\n\n# Promotion {.inverse}\n\n## Promoting your package\n\n- Some promotion will/may be done for you: [CRANberries](https://dirk.eddelbuettel.com/cranberries/), \nsearch engines (vignette/pkgdown site)\n- Some channels are obvious: personal website, blog, Mastodon (#RStats)\n- Publicize your new package via R Weekly \n - Add to the weekly news blog, see [CONTRIBUTING](https://github.com/rweekly/rweekly.org/blob/gh-pages/CONTRIBUTING.md), and example pull requests [new package](https://github.com/rweekly/rweekly.org/pull/279), [new version](https://github.com/rweekly/rweekly.org/pull/277).\n- Would your package fit in a CRAN Task View? \n - Check [GitHub organization](https://github.com/cran-task-views/ctv) for how to propose addition.\n \n::: {.notes}\nAnd Twitter, if you must.\n:::\n\n## Talks\n\n- Meetups: Warwick RUG, Coventry R-Ladies (or your local groups)\n- Conferences \n - **General**: useR!, posit::conf, satRdays\n - **Specific**: R/Finance, BioC, Psychoco\n - **Non R-specific**: Royal Statistical Society (RSS), ???\n- Conferences provide greater exposure, particular to people working in relevant\nfield(s).\n- Don't forget to share your slides! (Conference/personal website, LinkedIn, RPubs, Slideshare)\n\n## Paper\n\n:::{.smaller90}\n- A paper not only promotes your package but benefits from peer review\n - Paper can also overlap with vignette\n- Traditional journals:\n - **Open Source Software**: The R Journal, Journal of Statistical Software\n - **Computing**: Computational Statistics and Data Analysis, Journal of \n Computational and Graphical Statistics, SoftwareX\n - **Science**: Bioinformatics, PLOS ONE, Method in Ecology and Evolution\n- Alternative journals:\n - F1000research Bioconductor/R package gateway: publish, then open review\n - [Journal Open Source Software](https://joss.theoj.org/): open code review, short descriptive paper\n::: \n\n# Maintenance {.inverse}\n\n## `usethis::use_upkeep_issue()`\n\nThis is a new function in **usethis**. Like `usethis::use_release_issue()`, it opens a GitHub issue with an (opinionated) to-do list of tasks that should be ticked off for your package (at least) once a year.\n\nThe **tidyverse** team think of this like 'spring cleaning' for packages.\n\nBlog post: [Package spring cleaning](https://www.tidyverse.org/blog/2023/06/spring-cleaning-2023/)\n\n## Interacting with users\n\n- Bug reports/help requests\n - Can show where documentation/tests need improving\n - Help you find out who's using your package and what for\n - Can give ideas for new features\n - Can lead to collaborations\n- Avoid using email, so that other people can benefit\n - GitHub issues\n - Stackoverflow questions \n \n## Interacting with developers\n\n:::{.smaller80}\n* Write developer documentation -- remember you can add non-vignette articles with `usethis::use_article()`\n* Add a code of conduct, e.g. Contributor Covenant\n\n ::: {.cell layout-align=\"center\"}\n \n ```{.r .cell-code}\n usethis::use_code_of_conduct()\n ```\n :::\n\n* Add a CONTRIBUTING.md to your GitHub repository\n - Do you have a style guide?\n - Reminders to run check/tests/add NEWS item to pull requests\n* Use tags to highlight issues: the following are promoted by GitHub, e.g. `help wanted`, `good first issue`\n* Add topics to your GitHub repo so potential contributors can find it \n:::\n\n## Consider the longer-term\n\n* Work on new features and bug fixes for the next release\n* Buddy-up\n - Review each other's code\n - Co-author each other's packages\n* Take advantage of events e.g. [Hacktoberfest](https://hacktoberfest.digitalocean.com/), Closember \n* Start work on your next package!\n\n## Congratulations 🎉 {.inverse .center .center-h}\n\nYou have written a package!\n\n## We value your feedback\n\nPlease take a few minutes to complete this anonymous [feedback form](https://docs.google.com/forms/d/e/1FAIpQLSenADnqVZfmWCTlz1VMMfuod1qFcqqWd0kaj6ekZ4Y6QFAzlQ/viewform?usp=dialog)\n\nThanks!\n\n# End matter {.inverse}\n\n## References\n\nWickham, H and Bryan, J, _R Packages_ (2nd edn, in progress), .\n\nR Core Team, _Writing R Extensions_, \n\nrOpenSci Packages: Development, Maintenance, and Peer Review \n\nrOpenSci Statistical Software Peer Review (especially Chapter 3: Guide for Authors) \n\n## License\n\nLicensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License ([CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/){target=\"_blank\"}).\n",
+ "markdown": "---\ntitle: Packaging dataPublication and maintenance\nsubtitle: R package development workshop
Module 5\nauthor: Forwards teaching team\nformat: forwardspres-revealjs\n---\n\n## Overview\n\n- Publication\n - GitHub\n - R-Universe\n - CRAN\n- Promotion\n- Maintenance\n- *Workshop admin*\n\n::: {.notes}\nThe packaging data section would more naturally fit earlier in the course, but put here because of how the schedule has panned out. \n:::\n\n# Publication {.inverse}\n\n# GitHub {.inverse}\n\n## Your package is already on GitHub\n\nSince your package is already on GitHub, any R user can install it with\n\n```r\nremotes::install_github(\"USER/REPO\")\n```\n\nIf you want to tag it as a release, make sure there's a `NEWS.md` file then run\n\n```r\nusethis::use_version() # set the release version number\n```\n\nCheck the `NEWS.md` file is up-to-date (`use_version()` will modify it) then \n\n```\nusethis::use_github_release()\n```\n\nThis will bundle the source code as a `zip` and a `tar.gz` and make them available from the **Releases** section of the repo homepage.\n\n::: {.notes}\nSee previous session for details about NEWS.md and `usethis::use_news_md()`\n\nuse_github_release() is also part of the CRAN submission process, towards the end of the `use_release_issue()` to-do list.\n:::\n\n# R-Universe {.inverse}\n\n## R-Universe\n\nWith [R-Universe](https://r-universe.dev/), you can create a personal, CRAN-like repository.\n\nYou're in control of what's published in your R-Universe! \n\nIt is a good way to allow users to easily install packages without going through the rigour of the CRAN submission process.\n\nUseful resources:\n\n- Search the whole R-universe: \n- About the R-universe: \n- R-universe help-page: \n\n::: {.notes}\nA project from rOpenSci \n:::\n\n## Installing a package from an R-universe\n\nBinaries are built for Windows and MacOS, which a user can install using \n`install.packages()`, e.g.\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\n# Install 'warwickplots' from the 'warwick-stats-resources' universe\ninstall.packages('warwickplots', repos = c(\n WSR = 'https://warwick-stats-resources.r-universe.dev',\n CRAN = 'https://cloud.r-project.org')\n)\n```\n:::\n\n\n. . .\n\nAlternatively, you can first set `options(repos)` to enable favourite repositories by default:\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\noptions(repos = c(\n WSR = 'https://warwick-stats-resources.r-universe.dev',\n CRAN = 'https://cloud.r-project.org')\n)\ninstall.packages(\"warwickplots\")\n```\n:::\n\n\n\n::: {.notes}\nGive an aside about the warwickplots package\n\nNote that we need to list CRAN as r-universe packages may have dependencies on CRAN packages.\n\nTo make options persist across sessions, add this code to your .RProfile with `usethis::edit_r_profile()`\n\nCRAN repo is listed because r-universe package may have dependencies on packages on CRAN.\n:::\n\n## Create your R-universe\n\nFollow the official R-Universe: [Set up your own universe](https://docs.r-universe.dev/publish/set-up.html/). \n\n:::{.smaller80}\nIn a nutshell:\n\n1. Create a repository called `.r-universe.dev` on the GitHub account for `username`, e.g. . The repository must contain a file called [packages.json](https://github.com/maelle/maelle.r-universe.dev/blob/main/packages.json) in the standard format, defining at least the `package` name and git `url` for the packages you want to include, e.g.\n \n ```\n [\n {\n \"package\": \"warwickplots\",\n \"url\": \"https://github.com/Warwick-Stats-Resources/warwickplots\"\n }\n ]\n ```\n\n2. Install the [r-universe app](https://github.com/apps/r-universe/installations/new) on the GitHub account that you want to enable. Choose __enable for all repositories__ when asked.\n:::\n\n::: {.notes}\nStill using `maelle` in places as shorter that Warwick-Stats-Resources! \nAlso, nice to give a shout-out to her and her role in rOpenSci.\n\nCopying the example from the r-universe help page, with the example/links to Maelle, but using the example json from WSR to be consistent with previous slide. \n\nMight be worth pointing out that with actual username, don't need `< >`\n:::\n\n## What happens next\n\n- After a few minutes, your source universe will appear on: `https://github.com/r-universe/`\n\n- The universe automatically starts building the packages from your registry. Once finished, they will appear on `https://.r-universe.dev`\n\n- The universe automatically syncs and builds your package git repos once per hour.\n\n- If you encounter any issues, the actions tab in your source universe may show what is going on, for example: \n\n- Or check the [R-Universe documentation](https://docs.r-universe.dev/).\n\n# CRAN {.inverse}\n\n## Why publish on CRAN?\n\n- Sign of quality\n\n - Code is ready to be used (not a beta version)\n - Basic standards: documented code, running examples, etc\n - Works with current version of R and other packages \n - Commitment of maintainer\n- Discoverability\n- Ease of installation\n- Bioconductor, rOpenSci: even higher standards, code review\n\n## It's an involved process\n\n- Read the official [Checklist for CRAN Submissions](https://cran.r-project.org/web/packages/submission_checklist.html) \nto check requirements beyond the automated checks.\n\n- Read the community-created [Prepare for CRAN](https://github.com/ThinkR-open/prepare-for-cran) checklist.\n\n- Useful functions for additional checks:\n - `goodpractice::gp()`\n - `spelling::spell_check_package()`\n\n## `usethis::use_release_issue()`\n\nThis function will first ask you to select the release version (major, minor, patch) then create and open a to-do list as an issue in the package GitHub repo.\n\nFor a first submission, there are around **22** tasks to complete, split into sections, to follow (more-or-less) in order:\n\n- First release (one-time only)\n- Prepare for release\n- Submit to CRAN\n- Wait for CRAN (things to do after package has been accepted)\n\nFor more details on each, see the [Releasing to CRAN](https://r-pkgs.org/release.html) chapter of the R Packages book.\n\n::: {.notes}\nNumber of tasks may vary depending on what you've already done (e.g. use_news_md will appear on list if you haven't already got a NEWS.md file, but won't if you do.)\n\nSome are clearly optional (e.g. drafting a blog post about the release) but most should be followed.\n\nSome relate to promoting the package, rather than the technicalities of releasing it.\n\nThere are some different items for packages already on CRAN - not covered here - see Release chapter of R Packages for more details\n\nWill catch many common 'gotchas', e.g. Title Case for Title, checking all exported functions have @returns and @examples\n:::\n\n## Run \"as CRAN\" checks\n\n[CRAN policies](https://cran.r-project.org/web/packages/policies.html) state that you must run `R CMD check --as-cran` _on the tarball to be uploaded_ with the current version of R-devel.\n\nFirst make sure the package passes check locally:\n```r\ndevtools::check()\n```\n\nThen allow some extra checks:\n```r\ndevtools::check(remote = TRUE, manual = TRUE)\n```\n\nThen send to CRAN's win-builder to check on R-devel\n```r\ndevtools::check_win_devel()\n```\n\nAlso check on Mac (M1)\n\n```r\ndevtools::check_mac_release()\n```\n\n::: {.notes}\nIt's possible that the way your libraries are set up can mask problems with `check()` on your local machine. For example, it's important that your System Library just comes with base and recommended packages and that all packages that you install go in your user library. Aside: Installing R through `rig` takes care of this for you. \n:::\n\n## R-hub v2\n\n- A new (since April 2024) check system.\n- Works best if the package is on GitHub\n- Works with GitHub Actions\n\n\n::: {.cell layout-align=\"center\"}\n\n```{.r .cell-code}\n# run once\ninstall.packages(\"rhub\") \nrhub::rhub_setup() # guides through set-up process\nrhub::rhub_doctor() # checks the set-up\n\n# run the checks\nrhub::rhub_check()\n```\n:::\n\n\n\nSee [the r-hub blog post](https://blog.r-hub.io/2024/04/11/rhub2/) for more details\n\n## `cran-comments.md`\n\nWrite submission notes, generating the `cran-comments.md` file with\n```r\nusethis::use_cran_comments()\n```\n```\n\n ## Test environments\n * local OS X install (R-release)\n * win-builder (R-release, R-devel) \n\n ## R CMD check results\n\n 0 errors | 0 warnings | 1 note\n\n * This is a new release.\n```\n\nThere’s always one note for a new submission.\n\n::: {.notes}\nuse_cran_comments() will populate cran-comments.md with the R CMD check results section. \n\nThe test environments section needs to be filled by hand\n:::\n\n## Submit to CRAN\n\n```{.r}\ndevtools::release()\n```\n\nThis asks you questions which you should carefully read and answer.\n\n::: {.notes}\nThe use_release_issue() function uses devtools::submit_cran() rather than devtools::release(), but the documentation page for submit_cran() recommends using release() instead as it performs more checks. \n:::\n\n## If your submission fails\n\nDo not despair! It happens to everyone, even R-core members.\n\nIf it’s from the CRAN robot, just fix the problem & resubmit.\n\nIf it’s from a human, do not respond to the email and do not argue. Instead update `cran-comments.md` & resubmit.\n\n## For resubmission\n\n```\n This is a resubmission. Compared to the last submission, I\n have:\n\n * First change.\n * Second change.\n * Third change.\n\n --\n\n ## Test environments\n * local OS X install, R 3.2.2\n * win-builder (devel and release)\n\n ## R CMD check results\n ...\n```\n\n## Subsequent submissions to CRAN\n\nProceed as before. If you have reverse dependencies you need to also run \n`R CMD check` on them, and notify CRAN if you have deliberately broken them.\n\nFortunately the **revdepcheck** package makes this fairly easy\n\n```r\nremotes::install_github(\"r-lib/revdepcheck\")\nusethis::use_revdep()\n\nrevdepcheck::revdep_check()\nrevdepcheck::revdep_report_cran() # get intermediate report for cran \n```\n\n# Promotion {.inverse}\n\n## Promoting your package\n\n- Some promotion will/may be done for you: [CRANberries](https://dirk.eddelbuettel.com/cranberries/), \nsearch engines (vignette/pkgdown site)\n- Some channels are obvious: personal website, blog, Mastodon (#RStats)\n- Publicize your new package via R Weekly \n - Add to the weekly news blog, see [CONTRIBUTING](https://github.com/rweekly/rweekly.org/blob/gh-pages/CONTRIBUTING.md), and example pull requests [new package](https://github.com/rweekly/rweekly.org/pull/279), [new version](https://github.com/rweekly/rweekly.org/pull/277).\n- Would your package fit in a CRAN Task View? \n - Check [GitHub organization](https://github.com/cran-task-views/ctv) for how to propose addition.\n \n::: {.notes}\nAnd Twitter, if you must.\n:::\n\n## Talks\n\n- Meetups: Warwick RUG, Coventry R-Ladies (or your local groups)\n- Conferences \n - **General**: useR!, posit::conf, satRdays\n - **Specific**: R/Finance, BioC, Psychoco\n - **Non R-specific**: Royal Statistical Society (RSS), ???\n- Conferences provide greater exposure, particular to people working in relevant\nfield(s).\n- Don't forget to share your slides! (Conference/personal website, LinkedIn, RPubs, Slideshare)\n\n## Paper\n\n:::{.smaller90}\n- A paper not only promotes your package but benefits from peer review\n - Paper can also overlap with vignette\n- Traditional journals:\n - **Open Source Software**: The R Journal, Journal of Statistical Software\n - **Computing**: Computational Statistics and Data Analysis, Journal of \n Computational and Graphical Statistics, SoftwareX\n - **Science**: Bioinformatics, PLOS ONE, Method in Ecology and Evolution\n- Alternative journals:\n - F1000research Bioconductor/R package gateway: publish, then open review\n - [Journal Open Source Software](https://joss.theoj.org/): open code review, short descriptive paper\n::: \n\n# Maintenance {.inverse}\n\n## `usethis::use_upkeep_issue()`\n\nThis is a new function in **usethis**. Like `usethis::use_release_issue()`, it opens a GitHub issue with an (opinionated) to-do list of tasks that should be ticked off for your package (at least) once a year.\n\nThe **tidyverse** team think of this like 'spring cleaning' for packages.\n\nBlog post: [Package spring cleaning](https://www.tidyverse.org/blog/2023/06/spring-cleaning-2023/)\n\n## Interacting with users\n\n- Bug reports/help requests\n - Can show where documentation/tests need improving\n - Help you find out who's using your package and what for\n - Can give ideas for new features\n - Can lead to collaborations\n- Avoid using email, so that other people can benefit\n - GitHub issues\n - Stackoverflow questions \n \n## Interacting with developers\n\n:::{.smaller80}\n* Write developer documentation -- remember you can add non-vignette articles with `usethis::use_article()`\n* Add a code of conduct, e.g. Contributor Covenant\n\n ::: {.cell layout-align=\"center\"}\n \n ```{.r .cell-code}\n usethis::use_code_of_conduct()\n ```\n :::\n\n* Add a CONTRIBUTING.md to your GitHub repository\n - Do you have a style guide?\n - Reminders to run check/tests/add NEWS item to pull requests\n* Use tags to highlight issues: the following are promoted by GitHub, e.g. `help wanted`, `good first issue`\n* Add topics to your GitHub repo so potential contributors can find it \n:::\n\n## Consider the longer-term\n\n* Work on new features and bug fixes for the next release\n* Buddy-up\n - Review each other's code\n - Co-author each other's packages\n* Take advantage of events e.g. [Hacktoberfest](https://hacktoberfest.digitalocean.com/), Closember \n* Start work on your next package!\n\n## Congratulations 🎉 {.inverse .center .center-h}\n\nYou have written a package!\n\n## We value your feedback\n\nPlease take a few minutes to complete this anonymous [feedback form](https://docs.google.com/forms/d/e/1FAIpQLSenADnqVZfmWCTlz1VMMfuod1qFcqqWd0kaj6ekZ4Y6QFAzlQ/viewform?usp=dialog)\n\nThanks!\n\n# End matter {.inverse}\n\n## References\n\nWickham, H and Bryan, J, _R Packages_ (2nd edn, in progress), .\n\nR Core Team, _Writing R Extensions_, \n\nrOpenSci Packages: Development, Maintenance, and Peer Review \n\nrOpenSci Statistical Software Peer Review (especially Chapter 3: Guide for Authors) \n\n## License\n\nLicensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License ([CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/){target=\"_blank\"}).\n",
"supporting": [],
"filters": [
"rmarkdown/pagebreak.lua"
diff --git a/prerequisites.qmd b/prerequisites.qmd
index 2c3d129..68820f9 100644
--- a/prerequisites.qmd
+++ b/prerequisites.qmd
@@ -2,7 +2,7 @@
title: Prerequisites
---
-*Last updated: May 11th, 2026*
+*Last updated: May 12th, 2026*
## Prior knowledge
@@ -15,15 +15,6 @@ Two of the modules from the Warwick-Stats-Resources R Foundations course covers
- [Introduction to R and RStudio](https://warwick-stats-resources.github.io/r-foundations/content/01-intro/)
- [Programming in R](https://warwick-stats-resources.github.io/r-foundations/content/03-programming/)
-## git and GitHub
-
-Although there will be some time dedicated to this in the workshop, it would be advantageous if you already have:
-
-- `git` installed on your computer. See
-- a [GitHub](https://github.com) account
-- a GitHub PAT configured to work with RStudio -- the vignette from the usethis package on [Managing Git(Hub) Credentials](https://usethis.r-lib.org/articles/git-credentials.html) goes through this.
-
-[Happy Git and GitHub for the useR](https://happygitwithr.com/) is an excellent resource for troubleshooting git related issues and checking that your setup works. Note that while the git/GitHub setup is convenient for sharing packages, you can create a package locally without it.
## R and RStudio
@@ -37,11 +28,11 @@ Download the pre-compiled binary for your OS from https://cloud.r-project.org/ a
**For Windows**
-Click "Download R for Windows", then "base", then "Download R-4.5.0 for Windows". This will download an `.exe` file; once downloaded, open to start the installation.
+Click "Download R for Windows", then "base", then "Download R-4.6.0 for Windows". This will download an `.exe` file; once downloaded, open to start the installation.
**For Mac**
-Click "Download R for macOS", then "R-4.5.0-arm64.pkg" (the first option) to download the installer for Macs with **Apple Silicon** chips or "R-4.5.0-x86_64.pkg" (the second option) to download the installer for Macs with **Intel** chips. Run the installer to complete installation.
+Click "Download R for macOS", then "R-4.6.0-arm64.pkg" (the first option) to download the installer for Macs with **Apple Silicon** chips or "R-4.6.0-x86_64.pkg" (the second option) to download the installer for Macs with **Intel** chips. Run the installer to complete installation.
**For Linux**
@@ -63,7 +54,7 @@ Download the relevant installer for your OS listed under "Installers for Support
### Development Tools
-Some additional tools may be required to compile R packages from source.
+Some additional tools are required to compile R packages from source, which is a necessary part of the package development process. These tools are not part of a typical R/RStudio setup so please follow the steps below to install them.
**For Windows with no admin rights**
@@ -96,3 +87,16 @@ If you installed `r-base-dev`, when installing R, you should have all you need
to build packages from source. Otherwise return to the instructions for
installing R for your distribution and follow the instructions there to install
the additional tools.
+
+## git and GitHub
+
+Although there will be some time dedicated to this in the workshop, it would be advantageous if you already have:
+
+- `git` installed on your computer. See
+- a [GitHub](https://github.com) account
+- a GitHub PAT configured to work with RStudio -- the vignette from the usethis package on [Managing Git(Hub) Credentials](https://usethis.r-lib.org/articles/git-credentials.html) goes through this.
+
+[Happy Git and GitHub for the useR](https://happygitwithr.com/) is an excellent resource for troubleshooting git related issues and checking that your setup works.
+
+Whilst git/GitHub isn't essential for package development, it is best practice and we will be making use of GitHub features during the course, e.g. publishing a package documentation website using GitHub pages. However, you can create a package locally without it.
+
diff --git a/slides/01-package-foundations/index.qmd b/slides/01-package-foundations/index.qmd
index 32a8354..cdac885 100644
--- a/slides/01-package-foundations/index.qmd
+++ b/slides/01-package-foundations/index.qmd
@@ -266,7 +266,9 @@ Option 2
We'll be using the following tools for package development:
- RStudio: to manage and edit the package source code
+ - Feel free to use any IDE you're comfortable with
- git + GitHub: to version control the package source code
+ - See if unfamiliar
- **devtools** and **usethis** R packages:
- **devtools** for functions supporting the development workflow
- **usethis** for setup tasks
@@ -344,6 +346,15 @@ It's also a good idea to vaccinate. This implements best practice by adding file
usethis::git_vaccinate()
```
+## Default branch
+
+Set the default branch to "main" (globally)
+
+```{r}
+#| eval: false
+usethis::git_default_branch_configure(name = "main")
+```
+
## Create a GitHub PAT
The **usethis** package uses personal access tokens (PAT) to communicate with GitHub.
@@ -536,10 +547,10 @@ usethis::use_github()
```
```{r eval = FALSE}
- ✔ Creating GitHub repository 'Warwick-Stats-Resources/animalsounds'
- ✔ Setting remote 'origin' to 'https://github.com/Warwick-Stats-Resources/animalsounds.git'
- ✔ Setting URL field in DESCRIPTION to 'https://github.com/Warwick-Stats-Resources/animalsounds'
- ✔ Setting BugReports field in DESCRIPTION to 'https://github.com/Warwick-Stats-Resources/animalsounds/issues'
+ ✔ Creating GitHub repository 'forwards/animalsounds'
+ ✔ Setting remote 'origin' to 'https://github.com/forwards/animalsounds.git'
+ ✔ Setting URL field in DESCRIPTION to 'https://github.com/forwards/animalsounds'
+ ✔ Setting BugReports field in DESCRIPTION to 'https://github.com/forwards/animalsounds/issues'
There is 1 uncommitted file:
* 'DESCRIPTION'
Is it ok to commit it?
@@ -551,10 +562,12 @@ usethis::use_github()
Choose the affirmative option! (The exact options may vary.)
+Note that you will see `/animalsounds` instead of `forwards/animalsounds`.
+
::: {.notes}
Take a look at the repo on GitHub. There is no `/R` folder as that folder is empty at the moment!
-During the demo, will need to run `use_github("Warwick-Stats-Resources")` as by default use_github goes to my personal repo
+During the demo, will need to run `use_github("forwards")` as by default use_github goes to my personal repo
:::
## Adding functions
@@ -648,6 +661,11 @@ To actually install the package:
- from GitHub: `remotes::install_github("USERNAME/REPO")` or `pak::pak("USERNAME/REPO")`
+# Minute cards {.inverse}
+
+- [Cohort 1](https://tally.so/r/ODdWrY)
+- [Cohort 2](https://tally.so/r/Zj15YB)
+
# End matter {.inverse}
## References
diff --git a/slides/02-documentation/index.qmd b/slides/02-documentation/index.qmd
index cc5c993..490993f 100644
--- a/slides/02-documentation/index.qmd
+++ b/slides/02-documentation/index.qmd
@@ -9,13 +9,30 @@ format: forwardspres-revealjs
- Documenting functions with roxygen2
- NAMESPACE: exporting functions
+- Dependencies
- NAMESPACE: importing functions
# Function documentation with roxygen2 {.inverse}
## roxygen2
-The **roxygen2** package generates documentation from specially formatted comments, that we write above the function code, e.g.
+The [**roxygen2**](https://roxygen2.r-lib.org/index.html) package generates documentation from specially formatted comments.
+
+comments -> `.Rd files` -> HTML
+
+This powers R's help system, e.g. `?function` and package websites.
+
+**roxygen2** 8.0.0 was released May 2026, with over 100 improvements and bug fixes.
+
+[This blog post](https://opensource.posit.co/blog/2026-05-01_roxygen2-8-0-0/) outlines the major changes.
+
+```{r}
+packageVersion("roxygen2")
+```
+
+## roxygen2 comments
+
+We write comments above the function code, e.g.
```{r, eval = FALSE}
#' @param x A numeric vector.
@@ -179,7 +196,7 @@ Internal | External
--------------------------- | -------------
Only for use within package | For use by others
Documentation optional | Must be documented
-Easily changed | Changing will break other people’s code
+Easily changed | Changing could break other people’s code
## Default NAMESPACE
@@ -213,8 +230,6 @@ NAMESPACE for each function that has an `#' @export` comment.
export(fun1)
```
-
-
## What to export
Only export functions that you want your package users to use, i.e. those that are relevant to the purpose of the package.
@@ -276,7 +291,7 @@ Most commonly used mark-up is easier with markdown (and can be mixed with `.Rd`
* To a function in a different package: `[pkg::func()]`
* With different link text, e.g. `[link text][func()]`
-For more details, see the [(R)Markdown support](https://cran.r-project.org/web/packages/roxygen2/vignettes/rd-formatting.html) vignette.
+For more details, see the [(R)Markdown support](https://roxygen2.r-lib.org/articles/rd-formatting.html) vignette.
::: {.notes}
Seems you no longer need to specify `pkg::` - will find the documentation in any installed package. For functions in multiple packages, e.g. `select()` help pane will offer a choice. Probably still best practice to use `pkg::` for disambiguation, though still may not be necessary for base functions
@@ -285,7 +300,7 @@ Seems you no longer need to specify `pkg::` - will find the documentation in any
## Your turn
1. Add some details to the help page for `animal_sounds()`, with a link to `paste0()` and some markdown syntax.
-2. Add a link to a function from a package you don't have installed (perhaps `basemodels::dummy_classifier()`).
+2. Add a link to a function from a package you don't have installed (perhaps `grumpy::read_npy()`).
3. Run `devtools::document()` and check the link in the help page. What happens?
4. Run `devtools::check()`. Does the link cause problems?
5. Delete the link to the package you don't have installed and run `devtools::document()` again.
@@ -299,6 +314,15 @@ In 3, the link will still be created (and will work if you subsequently install
# Dependencies {.inverse}
+## No `library()` calls!
+
+We **cannot** use `library()` calls in R packages.
+
+We need another way to access functions in other packages,
+and to ensure that users of our package have those other packages installed on their system too.
+
+To do this, we can take **dependencies** on other packages.
+
## Dependencies
Dependencies are other R packages that our package uses. There are three types of dependency:
@@ -363,28 +387,56 @@ By default, packages will be added to "Imports".
```{r}
#| eval: false
-usethis::use_package("rlang")
-usethis::use_package("glue", type = "Suggests")
+usethis::use_package("cli")
```
-# NAMESPACE: imports {.inverse}
-
-## You might get tired of using `::` all the time
-
-Or you might want to use an infix function
+```
+✔ Adding cli to Imports field in DESCRIPTION.
+☐ Refer to functions with `cli::fun()`.
+```
+. . .
```{r}
#| eval: false
-`%-=%` <- roperators::`%-=%`
+usethis::use_package("withr", type = "Suggests")
+```
-center <- function(df, select) {
- for (nm in names(df[select])){
- # overwrite column after subtracting the mean
- df[[nm]] %-=% mean(df[[nm]])
- }
- df
-}
```
+✔ Adding withr to Suggests field in DESCRIPTION.
+☐ Use `requireNamespace("withr", quietly = TRUE)` to test if
+ withr is installed.
+☐ Then directly refer to functions with `withr::fun()`.
+```
+
+# NAMESPACE: imports {.inverse}
+
+## Accessing functions in other packages
+
+Once we have taken a dependency on a *package*,
+we have a choice about how to access the *functions* in that package:
+
+- directly, with `pkgname::function()`
+- importing the function, then just calling `function()`
+
+## Advantages of `pkgname::function()`
+
+- Makes it really clear to you, and other readers of your code, where functions have come from.
+- Requires no further setup
+- Necessary to dissambiguate when have two functions with the same name in two different packages
+
+## Advantages of importing a function
+
+- Don't need to keep typing `pkgname::` - this can get tedious and make code much more noisy
+- Code is slightly more efficient to run (though only by about 2 microseconds)
+ - Difference will only be noticeable if running 100,000+ calls in a tight loop
+- Some packages already have function names that make it clear where they are from, e.g. **stringr** with `str_*()`
+- Necessary for infix operators, e.g. `%>%`
+ - N.B. recommendation is now to use native pipe `|>` in packages instead.
+
+. . .
+
+Largely a matter of personal preference. A hybrid approach is also fine!
+
## Aside: `%>%` vs `|>`
@@ -402,7 +454,9 @@ Depends:
- Use the methods outlined in [this tidyverse blog post](https://www.tidyverse.org/blog/2023/04/base-vs-magrittr-pipe/#using-the-native-pipe-in-packages) to ensure the package can still work with older versions of R.
-## You can `import` functions into the package
+See [slides 28-31 here](https://warwick-stats-resources.github.io/r-foundations-2025/slides/02-data-wrangling/index.html#/a-note-about-pipes-vs) for more about the pipes, and [this blog post](https://ivelasq.rbind.io/blog/understanding-the-r-pipe/).
+
+## Importing functions into the package manually
```{r}
#| eval: false
@@ -419,29 +473,28 @@ col_summary <- function(df, fun) {
`devtools::document()` will add corresponding `import()` statements to the NAMESPACE, e.g. `import(purr, keep, modify)`.
-Adding formal imports is slightly more efficient than using `::`.
-
Here, the `@importFrom` tag is placed above the function in which the imported function is used.
-## Package-level import file
+## Package-level import file, manually
Imports belong to the package, not to individual functions, so alternatively you can recognise this by storing them in a central location, e.g. `R/animalsounds-package.R`
```r
#' @importFrom purrr keep modify
-#' @importFrom roperators %-=%
+#' @importFrom magrittr %>%
NULL
```
-::: {.notes}
-This removes the possibility of multiple (redundant) imports of the same function. But harder to remember to remove import if function changes! It's a matter of personal taste.
-:::
+This removes the possibility of multiple (redundant) imports of the same function.
+But harder to remember to remove import if function changes! It's a matter of personal taste.
## `usethis::use_import_from()`
There can be several steps to importing a function. `usethis::use_import_from()` takes care of all of them.
+This is a (preferred) alternative to writing `@importFrom` tags manually.
+
It will first create the package documentation file `R/animalsounds-package.R` (if it doesn't already exist -- you will also need to agree to this).
```{r}
@@ -462,7 +515,9 @@ use_import_from() is opinionated in implementing package-level import (rather th
May need to close and reopen R/animalsounds-package.R to see the changes.
:::
-## It may be tempting to import a whole package...
+## You *can* import all functions from a package...
+
+It may be tempting to import all the functions from a package:
```r
#' @import purrr
@@ -476,7 +531,9 @@ col_summary <- function(df, fun) {
```
-## ...but it is dangerous
+## ... but don't!
+
+**It is dangerous:**
```r
#' @import pkg1
@@ -484,13 +541,16 @@ col_summary <- function(df, fun) {
fun <- function(x) {
fun1(x) + fun2(x)
}
-
```
Works today...
... but next year, what if **pkg2** adds a `fun1` function?
+**And not clear:**
+
+You lose direct evidence in your package of which functions come from which packages.
+
## Metapackages
It is bad practice to import "metapackages" (i.e. packages that are collections of packages), such as **tidyverse**.
@@ -503,8 +563,8 @@ See the blog post Testing
subtitle: R package development workshop
Module 3
author: Forwards teaching team
format: forwardspres-revealjs
@@ -13,6 +13,15 @@ format: forwardspres-revealjs
# Packaging data {.inverse}
+## Why package data
+
+- The purpose of the package is to make data available
+ - e.g. [nycflights13](https://github.com/tidyverse/nycflights13), [palmerpenguins](https://github.com/allisonhorst/palmerpenguins)
+- To share (toy) data to use with the package functions
+ - e.g. [readr](https://github.com/tidyverse/readr)
+ - Useful for examples and vignettes
+- To use internally, e.g. look-up tables
+
## Including data
There are 3 types of data we might want to include:
@@ -140,23 +149,32 @@ system.file("extdata", "mtcars.csv", package = "readr")
5. Run `devtools::document()` to create the documentation for the `farm_animals` data. Preview the documentation to check it.
6. Commit all the changes to your repo.
+# Unit testing with testthat {.inverse}
+## You (almost certainly) already test your code
-# Unit testing with testthat {.inverse}
+You write code, run it, check outputs (maybe for a few different inputs).
-## Why test?
+Maybe you also use print statements for debugging.
-We build new functions one bit at a time.
+. . .
-What if a new thing we add changes the existing functionality?
+**Unit tests make your informal testing systematic so it scales with your package**
-How can we check and be sure all the old functionality still works with New Fancy Feature?
+## Testing beyond your own workflow
-Unit Tests!
+You are building something that others will use, in possibly unpredictable ways.
-::: {.notes}
-Gives confidence to package users as well
-:::
+- Future you (or contributors) will modify code and need to verify nothing broke
+- Users will pass inputs you didn't anticipate
+- Documentation alone won't prevent misuse
+
+## Practical benefits
+
+- Refactoring confidence: change internals or add new functionality without fear of breaking user-facing behavior
+- Regression prevention: every bug fix becomes a test that ensures it stays fixed
+- Living documentation: tests show how functions are actually meant to be used
+- Faster debugging: when something breaks, tests help isolate exactly where
## Set up test infrastructure
@@ -194,6 +212,13 @@ Test every individual task the function completes separately.
Check both for successful situations and for expected failure situations.
+::: {.callout-tip}
+Look at the `"tests/testthat"` directory and some test files in the GitHub repos for some well-respected packages to see how their tests are organised, e.g.
+
+-
+-
+:::
+
## Expectations
Three expectations cover the vast majority of cases
@@ -501,6 +526,11 @@ The [vdiffr](https://vdiffr.r-lib.org) package allows comparisons between SVG im
## When you stop work, leave a test failing. {.inverse .center .center-h}
+# Minute cards {.inverse}
+
+- [Cohort 1](https://tally.so/r/LZa1Yp)
+- [Cohort 2](https://tally.so/r/aQANEb)
+
# End matter {.inverse}
## References
diff --git a/slides/04-check-package-documentation/index.qmd b/slides/04-check-package-documentation/index.qmd
index 41dc0d4..3d7a44d 100644
--- a/slides/04-check-package-documentation/index.qmd
+++ b/slides/04-check-package-documentation/index.qmd
@@ -58,30 +58,71 @@ We haven't yet specified a license for our package.
On running `check()` you may get an error if you are using a networked drive. There's a fix coming in a few slides.
:::
-## Aside: in case of error
-
-On running `devtools::check()` you may get an error of the form
-
-```
-Updating animalsounds documentation
-Error: The specified file is not readable: path-to\animalsounds\NAMESPACE
+## A function that fails many checks
+
+```{r}
+#| eval: false
+#' Make an excited animal sound
+#'
+#' Repeat an animal sound in uppercase.
+#'
+#' @param sound A character string containing an animal sound.
+#' @param times Number of times to repeat the sound.
+#'
+#' @return A character vector.
+#'
+#' @examples
+#' excited_sound("moo", 3)
+#'
+#' @export
+excited_sound <- function(animal, sound, times = 3) {
+
+ sound <- str_to_upper(sound)
+
+ paste("The", animal, "says", paste(rep(sound, times), collapse = " "))
+}
```
-This can happen if your repo is on a networked drive.
-
-This is covered in this [Stackoverflow question](https://stackoverflow.com/questions/40530968/overwriting-namespace-and-rd-with-roxygen2) and can be fixed.
-
-## Aside: a fix for networked drives
-
-1. Save a copy of this file: [fix_for_networked_drives.R](../../R/fix_for_networked_drives.R)
-
- Save it somewhere other than the `animalsounds` directory
+## A function that fails many checks (cont.)
-2. Open the file from the `animalsounds` project session
-
-3. Run the whole file
-
-You should now find that `devtools::check()` proceeds normally.
+```r
+❯ checking examples ... ERROR
+ Running examples in 'animalsounds-Ex.R' failed
+ The error most likely occurred in:
+
+ > base::assign(".ptime", proc.time(), pos = "CheckExEnv")
+ > ### Name: excited_sound
+ > ### Title: Make an excited animal sound
+ > ### Aliases: excited_sound
+ >
+ > ### ** Examples
+ >
+ > excited_sound("moo", 3)
+ Error in str_to_upper(sound) : could not find function "str_to_upper"
+ Calls: excited_sound
+ Execution halted
+
+❯ checking Rd \usage sections ... WARNING
+ Undocumented arguments in Rd file 'excited_sound.Rd'
+ 'animal'
+
+ Functions with \usage entries need to have the appropriate \alias
+ entries, and all their arguments documented.
+ The \usage entries must correspond to syntactically valid R code.
+ See chapter 'Writing R documentation files' in the 'Writing R
+ Extensions' manual.
+
+❯ checking R code for possible problems ... NOTE
+ excited_sound: no visible global function definition for 'str_to_upper'
+ Undefined global functions or variables:
+ str_to_upper
+
+1 error ✖ | 1 warning ✖ | 1 note ✖
+Error: R CMD check found ERRORs
+Execution halted
+
+Exited with status 1.
+```
## Types of problem
@@ -221,25 +262,6 @@ In LICENSE:
Copyright 2023 ACME Ltd. All rights reserved.
```
-## Licensing considerations at universities
-
-:::{.callout-note appearance="simple"}
-[This slide is specific for The University of Warwick, but similar considerations are likely to be true at other Universities.]{.smaller80}
-:::
-
-:::{.smaller75}
-- Software is defined as a creative output (unlike scholarly works, e.g. thesis, conference paper)
-- The university owns the IP of any software created by Warwick PhD students and staff in the course of their work
-- Before making code public or publishing software under any license, contact Brendan at [B.Spillane@warwick.ac.uk](mailto:B.Spillane@warwick.ac.uk)
-
- - Permission to publish under an open source license likely to be granted for research code
- - Not necessary to obtain permission if open source software was part of grant proposal (as proposal will have already been checked by Research & Impact Services, who will have identified any IP issues).
-:::
-
-::: {.notes}
-Extra note from Brendan: "they don’t need to come to me with every single bit of code they open source. I’m more interested in the entirety of the project rather than approving 2000 bits of individual code!"
-:::
-
## Your turn
1. Open the DESCRIPTION file and add a title and description.
@@ -568,6 +590,11 @@ You can add more information to `_pkgdown.yml` to customise the package website:
5. Click on the link to the website under the **About** section of the repo.
6. (Bonus) Change the appearance of the site with a Bootswatch theme: .
+# Minute cards {.inverse}
+
+- [Cohort 1](https://tally.so/r/VLbEYy)
+- [Cohort 2](https://tally.so/r/kdJa7e)
+
# End matter {.inverse}
## References
@@ -580,3 +607,29 @@ R Core Team, *Writing R Extensions*, `
- If you encounter any issues, the actions tab in your source universe may show what is going on, for example:
+- Or check the [R-Universe documentation](https://docs.r-universe.dev/).
+
# CRAN {.inverse}
## Why publish on CRAN?
diff --git a/workshops/may-july-2026-cohort-2.qmd b/workshops/may-july-2026-cohort-2.qmd
index e4f5dc2..d077349 100644
--- a/workshops/may-july-2026-cohort-2.qmd
+++ b/workshops/may-july-2026-cohort-2.qmd
@@ -35,7 +35,7 @@ and make sure you register for all five **cohort 2** sessions (noting that there
## Welcome and introduction
-Here's a link to the [slides](may-july-2026-cohort-2.qmd){target="_blank"} in a new window.
+Here's a link to the [slides](may-july-2026-cohort-2-intro.qmd){target="_blank"} in a new window.
Here are the slides embedded: