9 In House R Packages

We have a number of packages that we use to complete our work. Packages are an assortment of functions grouped together because they are related in a certain way. It’s important to note that our packages are constantly involving, and we will be re-organizing them to place certain functions together with others that compartmentalize the package so that it more effectively completes specific tasks versus trying to be a tool for everything. Placing functions within packages allows us to document what it is that functions do and how they do it. Function documentation is provided within the gitpages which are served from a URL on the top right of the landing page. General information about the package is also found on these gitpages as well as the bottom of the repositories landing page.


Here is a brief description of the packages that we are currently developing and/or maintaining.

  • ngr - “New Graph Reporting” - a place to put random reporting functions related to New Graph Environment reporting. Super unstable and likely to change with functions often removed from here and put into more specific packages with names that are more fun.
  • exciter - This package focuses solely on “extra” functions related to citeing bibliography items such as processing .bib files to get citation keys, processing BiBtex keys to get inline citations, etc. We are calling it “extra” because we rely heavily on rbbt and standard rmarkdown::render magic (thorugh pandoc to do almost everything we need to do.
  • rfp - “Reproducible Field Projects British Columbia”. Goal of this package is to facilitate the creation and manipulation of spatial files with functions to facilitate reproducible workflows in field to office gis/environmental science planning, fieldwork and reporting. It is likely that much of the work that was previously done in the more general scripts repository dff-2022 will be moved to rfp.
  • fpr - “Fish Passage Reporting”. This package is used to clean data, QA, and build interactive reports related to fish passage planning, implementation and monitoring. Currently we also use fpr to access our remote PostgreSQL database with a suite of fpr_dbq_* prepended functions however that work will be migrated into a new package. For now - all new database related functions are being documented in ngr as ngr_dbq* prepended functions before they are migrated to their own package (funrdb?). There also many other functions that are not specific to fish passage reporting that historically were placed in this package (ex. fpr_photo_* (photo related functions), fpr_sp_* (spatial related functions)) that will eventually be placed in other packages. These functions will be evolved under different names within alternative packages over time with fpr versions likely soft deprecated (still working but which issue a message to the user to use the new function/package instead).
  • staticimports - although not an in-house package per se, we use a fork of this package by Winston Chang to manage functions that may be unstable and changing overtime. This package allows us to import specific functions into individual repositories into a static file usually called static imports.R so that we get a snapshot of its make up every time we import it. Our custom functions are pretended with the letter s (for static) and are contained within .R files pre-pended by the prefix ng_* found here. Of note - it is likely that we will migrate from using staticimports to something like burglr and/or renv in the future.

9.1 Writing Functions

  • Turning scripts into function for workflows that we use often can be very helpful for reproducibility and efficiency. Please read through writing good functions before moving on. Here are some additional things to remember when writing functions:

    • Add roxygen2 doccumentation to your function.
    • Name the function with a t (test) prefix to indicate that the function is for still in the testing phase, until it gets pulled into fpr. For example tfpr_db_query().
    • Call functions explicitly using ::, for example dplyr::mutate() and make sure all functions are included using the @importFrom syntax.
    • Include safety checks. You can use chk.
    • Define default values for parameters, even if they are = NULL.
    • Keep pipes simple by calling functions once and using , to separate variables. For example, put all case_when() calls in one mutate() call instead of multiple.
    • If certain numbers are being repeated in the function, consider defining them as params at the top of the function.
    • Avoid using getwd() because for most of our projects the working directory in a project is the main directory of the project.
    • Avoid using data.table functions, and instead use stringr.
  • Here are the steps for testing your function once it is written:

    • add your script as an R file in R directory.
    • run devtools::document().
    • run the devtools::check() or check from the build window, see 9.1. You need to have no errors to proceed.
    • run Test in that same window. Tests must pass to proceed.
    • add a bit of detail to news.md in main directory
    • run Install/Clean and Install, see 9.1.
    • Restart R in a repo outside of fpr. Load with library - Test it.
knitr::include_graphics("fig/build_check.png")
Using the `devtools::check` function

Figure 9.1: Using the devtools::check function