|
| 1 | +--- |
| 2 | +title: "Package design decisions" |
| 3 | +output: rmarkdown::html_vignette |
| 4 | +vignette: > |
| 5 | + %\VignetteIndexEntry{Package design decisions} |
| 6 | + %\VignetteEngine{knitr::rmarkdown} |
| 7 | + %\VignetteEncoding{UTF-8} |
| 8 | +--- |
| 9 | + |
| 10 | +```{r, include = FALSE} |
| 11 | +knitr::opts_chunk$set( |
| 12 | + collapse = TRUE, |
| 13 | + comment = "#>" |
| 14 | +) |
| 15 | +``` |
| 16 | + |
| 17 | +This page documents _vimcheck_ package design decisions as a guide to users, and to potential contributors seeking to extend this package or revise some of those decisions. |
| 18 | + |
| 19 | +Some design decisions that live in the background include: |
| 20 | + |
| 21 | +- _vimcheck_ is set up as a modern R package built with _devtools_, _usethis_, and _testthat_ (testing); |
| 22 | +- _vimcheck_ is documented using _roxygen2_ and _pkgdown_ for the package website; |
| 23 | +- _vimcheck_ is developed on GitHub and uses continuous integration workflows provided by GitHub Actions; |
| 24 | +- Any other decisions not covered here most likely follow advice in [Wickham and Bryan's _R Packages_](https://r-pkgs.org/). |
| 25 | + |
| 26 | +## Big picture |
| 27 | + |
| 28 | +_vimcheck_ is intended to collect, house, and be the single source for functionality used by VIMC to check submitted modelling outputs for discrepancies. |
| 29 | +This solves the immediate problem that this functionality is currently spread and repeated over multiple reports, increasing the potential for discrepancies and functionality drift in the tools. |
| 30 | +The overall goal is to improve the quality of VIMC's work by improving the reliability of VIMC outputs. |
| 31 | +The main users are currently intended to be members of the VIMC Secretariat, but may include VIMC consortium members in future. |
| 32 | + |
| 33 | +## Function organisation |
| 34 | + |
| 35 | +_vimcheck_ is currently developed in bursts, with each burst so far adding a set of data wrangling and plotting functions taken from a specific VIMC report. |
| 36 | + |
| 37 | +The package has two axes of organisation for its functionality: the theme or goal of the report from which the function comes, and what the function does. |
| 38 | + |
| 39 | +The current reports from which functions have been taken relate to: |
| 40 | + |
| 41 | +- Diagnostics on burden estimates provided by VIMC modelling groups, and |
| 42 | +- Pressure testing diagnostics intended to check for outliers in vaccine impact estimates. |
| 43 | + |
| 44 | +Functions are split into four categories, and the general idea is to have functionality be modular. |
| 45 | +As an example, _vimcheck_ favours functions that produce intermediate products that can be reused by multiple downstream functions (following the [DRY principle](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)). |
| 46 | + |
| 47 | +- Functions that work on data: This is the main functionality of the package and includes functions that work with raw or semi-processed data, such as burden or impact estimates; |
| 48 | +- Functions that prepare data for plotting: These are functions that sit between the data wrangling functions and plotting functions; |
| 49 | +- Plotting functions that are typically related to one upstream data-wrangling or plotting-preparation function; |
| 50 | +- Helper functions that provide useful but miscellaneous functionality. |
| 51 | + |
| 52 | +The general idea is to be able to set up small R pipelines within reports of the following form. |
| 53 | + |
| 54 | +```r |
| 55 | +# some data read in from a local source |
| 56 | +data |> |
| 57 | + fn_wrangle_data() |> |
| 58 | + fn_prep_data_for_plotting() |> |
| 59 | + fn_plot_data() |
| 60 | +``` |
| 61 | + |
| 62 | +The [function reference in the documentation](https://vimc.github.io/vimcheck/reference/index.html) is organised similarly. |
| 63 | + |
| 64 | +The R source code files in `./R/` are also organised in this way; for example `R/fn_burden_diagnostics.R` holds data-wrangling functions related to burden estimates, `R/fn_plotting_prep_bur_diag.R` holds functions to prepare wrangled data for plotting, and `R/fn_plotting_burden_diagnostics.R` holds plotting functions for the prepared data. |
| 65 | + |
| 66 | +## Package data |
| 67 | + |
| 68 | +_vimcheck_ includes some package data which is used to demonstrate and test its functionality. |
| 69 | +Some data is purely dummy data that follows the structure of data seen in VIMC reports. |
| 70 | +However, some data such as [eg_impact] is real VIMC data that has been released publicly as part of other packages. |
| 71 | + |
| 72 | +There is a number of package constants, which are single values or small vectors that are provided with and exported from the package. |
| 73 | + |
| 74 | +## Package dependencies |
| 75 | + |
| 76 | +We only list notable dependencies here. |
| 77 | + |
| 78 | +- [Tidyverse packages](https://www.tidyverse.org/) over base R or _data.table_; this is to keep functions within the dependency framework used in the reports from which they come --- we assume the report writers are also the package user-base and _vimcheck_ aims to be used, and friendly to use, for these people. |
| 79 | + |
| 80 | +- _cli_ and _glue_ for string interpolation and printing error messages to screen. |
| 81 | + |
| 82 | +- _diffdf_ to provide differences between data.frames. |
| 83 | + |
| 84 | +- _ggplot2_ for plotting; functions are not explicitly namespaced in many cases, but imported from the package to reduce code clutter in plotting function files. |
| 85 | + |
| 86 | +- _checkmate_ for input checking and to extend _testthat_. |
| 87 | + |
| 88 | +- [_vdiffr_](https://cran.r-project.org/package=vdiffr) for snapshot tests of plotting functions. |
| 89 | + |
| 90 | +### Data frames and tibbles |
| 91 | + |
| 92 | +Data-wrangling functions are agnostic to the type of tabular input, but always return a [tibble](https://tibble.tidyverse.org/) rather than a plain data.frame (if they return tabular data). |
| 93 | +This is because internal manipulation using Tidyverse functions often results in tibbles being produced (e.g. using `tidyr::pivot_*()`, or `dplyr::group_by()` followed by ungrouping), but inexplicably some Tidyverse functions preserve data.frames. |
| 94 | +We think it is preferable for users and developers to have a uniform function output type rather than have to guess whether it will be a tibble or a data.frame. |
| 95 | +A second reason is that tibbles are much easier to read when printed to screen. |
| 96 | + |
| 97 | +**Note that** all downstream functions --- plotting preparation and plotting functions --- that expect tabular data expect a tibble, and **will error** if they are not passed a tibble! |
| 98 | +This is partially to create some friction so that users check what they are passing: data processed with _vimcheck_ will always return a tibble, downstream functions only work on processed data, and errors might indicate that the wrong data are being passed. |
| 99 | + |
| 100 | +## Testing |
| 101 | + |
| 102 | +_vimcheck_ function are tested using package data (see above). |
| 103 | +As a result, tests focus on input checking and the form of outputs. |
| 104 | +There are comparatively few tests on correctness (e.g. are output numbers within a range), and this is a clear avenue for further development. |
0 commit comments