cd2030.core

Countdown to 2030 analysis of routine health facility data. cd2030.core loads a country’s facility data, checks its quality, adjusts it for incomplete reporting and outliers, chooses denominators, and computes coverage, inequality, mortality, service utilization, health system and family planning indicators, each with a chart. It also holds everything the Countdown Shiny apps share: the analysis pages, the Load Data wizard, the filters and the app frame (cd_app()), and Countdown’s content for the report builder (standard reports, the charts and tables a report can hold).

It is used in two ways:

Where it fits

DataSuite (VS Code based)
  └─ countdown-analytics            the DataSuite extension: lists the apps, adds the AI tools
       └─ cd2030.rmncah / cd2030.vaxx / cd2030.pooled    the apps, one R package each: run_app()
            └─ cd2030.core          THIS PACKAGE: analysis, Countdown pages, wizard, report content
                 └─ datasuite.ui    generic interface kit, chart options, report builder (knows nothing of Countdown)

Installation

install.packages(
  "cd2030.core",
  repos = c("https://damurka.r-universe.dev", "https://alkemalab.r-universe.dev", "https://cloud.r-project.org")
)

Many features use suggested packages: PDF export (chromote with Chrome, or Word/LibreOffice), editable PowerPoint charts (rvg), pictures (magick, rsvg, svglite, ragg), the Bayesian model. Install them with dependencies = TRUE. DataSuite installs them for the apps.

Using it from R

library(cd2030.core)

# A dataset: the Countdown Excel workbook (Admin, Population, Reporting and service sheets), a Stata .dta master
# file, or a saved .rds. The result is a CacheConnection: the data plus every choice made about it.
path <- system.file("extdata", "kenya.xlsx", package = "cd2030.core")
cache <- load_cache_data(path)
data <- cache$countdown_data      # the checked data (a cd_data tibble); load_data(path) gives just this

# Data quality
calculate_average_reporting_rate(data)
calculate_outliers_summary(data)
calculate_overall_score(data, threshold = 90)
plot(calculate_district_reporting_rate(data, threshold = 90))

# Adjustment, denominators and coverage go through the cache, which remembers each choice. Coverage also needs the
# national rates and survey estimates the Load Data wizard collects (cache$set_national_estimates(),
# cache$set_survey_estimates(), ...); the apps' pages show what each analysis needs.
cache$set_k_factors(c(anc = 0.25, idelv = 0.25, vacc = 0.25, opd = 0.25))   # opd only for rmncah
coverage <- cache$calculate_indicator_coverage("national")

# A standard report, written as Word (or "pdf", or "pptx" for a slide deck)
reports <- report_presets("en")
export_report(cache, reports[["data_quality"]], "data_quality.docx", format = "docx")

# Save the dataset and its choices next to the data, to reopen later with load_cache_data("kenya.rds")
cache$set_cache_path("kenya.rds")

The guides go through this step by step, with the output and charts each step gives: vignette("cd2030.core") to get started, then vignette("preparing-data"), vignette("data-quality") and vignette("coverage"). vignette("building-an-app") describes how the apps are built.

The functions are grouped by analysis step in the reference (help(package = "cd2030.core"), and the package overview ?cd2030.core). A few things worth knowing:

Building an app on it

An app is a small package whose run_app() says what is particular to it and calls cd_app(). cd2030.rmncah::run_app() is the complete example; in outline:

run_app <- function(language = "en", selected_file = NA) {
  set_selected_group("rmncah")                       # the app's indicator group
  options(
    cd2030.app_group = "rmncah",
    cd2030.config = list(                            # what the shared pages show for this app (see ?countdown-pages)
      nat_cov_indicators = c("anc4", "instlivebirths", "penta3", "measles1"),
      consistency_pairs = list(c("anc1", "penta1"), c("penta1", "penta3")),
      has_maternal = TRUE
    ),
    cd2030.help_dir = system.file("intro", package = "myapp")   # the Introduction page's help, per language
  )

  # translations (datasuite.ui's cd_translations()): datasuite.ui's, cd2030.core's (registered when it loads) and the
  # app's own file, merged
  i18n <- shiny.i18n::init_i18n(translation_json_path = cd_translations(system.file("translation", "translation.json", package = "myapp")))
  i18n$set_translation_language(language)
  cd_use_i18n(i18n)

  cd_app(
    app_name = "My app", app_version = "1.0.0", theme = "rmncah",
    nav_sections = list(cd_nav_start(), cd_nav_quality(), cd_nav_denominators()),  # the sidebar
    registry = my_pages(),                           # every page: the shared ones and the app's own
    i18n = i18n, language = language, selected_file = selected_file,
    # the Load Data screen, the same for every app; its fields come from options(cd2030.wizard = ...) (?countdown-pages)
    upload_ui = cd_upload_data_ui, upload_server = cd_upload_data_server
  )
}

?countdown-pages lists the shared pages, the Load Data wizard, the filters and the cd2030.config keys. The interface kit they are built from is documented in datasuite.ui (docs/README.md, docs/COMPONENTS.md).

Developing

devtools::load_all()     # work on the package
devtools::test()         # tests/testthat (uses inst/extdata/kenya.xlsx)
devtools::document()     # after changing roxygen comments
devtools::check()        # must stay at 0 errors, 0 warnings, 0 notes

Releasing

  1. Bump Version: in DESCRIPTION and add a section to NEWS.md.
  2. devtools::check() clean.
  3. Commit, tag (git tag -a vX.Y.Z -m "cd2030.core X.Y.Z") and push main and the tag.
  4. r-universe builds it from main (within minutes when its GitHub app is installed, otherwise within about an hour); see https://damurka.r-universe.dev/builds.
  5. If an app needs the new version, raise its cd2030.core (>= X.Y.Z) in the app’s DESCRIPTION.

See NEWS.md for what changed in each version.

Getting help

Report bugs at https://github.com/damurka/cd2030.core/issues.