Browsing the PhysioRecipes case database

PhysioRecipes is a version-controlled database of reproducible analysis case studies on public physiological data. Each case states a proposition, answers a question on a public dataset, and runs through to figures and a conclusion, with every reported number traced to an artifact and the whole operation DAG replayable byte-identically.

This package ships the verified run bundles plus a small API to browse the corpus. This vignette uses only that bundled metadata – it is fully offline and does not replay any case.

library(PhysioRecipes)

The corpus at a glance

list_cases() returns one row per case: its modality, the ecosystem packages it exercises, the dataset, the reproducibility status, and how many reported claims are grounded.

cases <- list_cases()
nrow(cases)
#> [1] 114
head(cases[, c("id", "modality", "status", "n_grounded", "n_claims")])
#>                        id
#> 1            adf-eegmmidb
#> 2   adl-freeliving-pamap2
#> 3          adl-har-ucihar
#> 4       adl-rasch-verbagg
#> 5        adl-selfcare-hmp
#> 6 adl-upperlimb-use-dsads
#>                                                                 modality
#> 1 eeg, time-series, stationarity, cross-tool-validation, signal-analysis
#> 2                   adl, wearable, free-living, physical-behaviour, enmo
#> 3                                      adl, wearable, har, mobility, icf
#> 4                             adl, psychometrics, rasch, outcome-measure
#> 5                                     adl, wearable, har, self-care, icf
#> 6                                    imu, accelerometry, upper-limb, adl
#>     status n_grounded n_claims
#> 1 verified          6        6
#> 2 verified          6        6
#> 3 verified          5        5
#> 4 verified          6        6
#> 5 verified          6        6
#> 6 verified          5        5

How many cases per modality and status:

sort(table(cases$status), decreasing = TRUE)
#> 
#>  verified validated 
#>       109         5
head(sort(table(cases$modality), decreasing = TRUE))
#> 
#>          gait, ground-reaction-force, pathology, cohort, cross-tool-validation 
#>                                                                              5 
#>                                                                  eeg, spectral 
#>                                                                              3 
#> accelerometer, wearable, physical-activity, free-living, cross-tool-validation 
#>                                                                              2 
#>                                             adl, wearable, har, self-care, icf 
#>                                                                              2 
#>                                                                       ecg, hrv 
#>                                                                              2 
#>        eeg, statistics, normality-test, cross-tool-validation, signal-analysis 
#>                                                                              2

Opening one case

get_case() parses a case’s case.json; case_path() and case_bundle() resolve its files on disk.

id <- cases$id[1]
case <- get_case(id)
case$title
#> [1] "Checking the assumption: the Augmented Dickey-Fuller test (a newly-authored op), bit-for-bit against statsmodels"
case$proposition
#> [1] "The ACF/PACF/AR folds assumed a stationary signal; the Augmented Dickey-Fuller (ADF) test checks that assumption -- is there a unit root (a random-walk drift) in the EEG, or is it stationary? The ecosystem had no unit-root test; this case introduces a NEWLY-AUTHORED op, adfTest. On a real eyes-closed posterior EEG channel its statistic reproduces statsmodels.tsa.stattools.adfuller(autolag=None) BIT-FOR-BIT (|diff| ~7e-15); the statistic (-22.36) lies ~19.5 below the 5% Dickey-Fuller critical value (-2.86), decisively rejecting the unit-root null -- the segment is stationary (no drift over 10 s), retroactively justifying the stationarity assumption of the companion folds."
# The verified evidence bundle (prereg, op-DAG, artifact, claims, report):
list.files(case_bundle(id))
#> [1] "benchmark_table.csv"      "claims.json"             
#> [3] "prereg.json"              "PROVENANCE.md"           
#> [5] "report.md"                "run_manifest.json"       
#> [7] "scientific_report.json"   "terminal_table.csv"      
#> [9] "verification_report.json"

Checking the invariants

validate_cases() applies the structural gate every case must satisfy (public dataset, every claim grounded, a byte-identical replay recorded). Here we check the first few; omit ids to gate the whole corpus.

validate_cases(ids = head(cases$id, 5))
#>                      id   status   ok reason
#> 1          adf-eegmmidb verified TRUE       
#> 2 adl-freeliving-pamap2 verified TRUE       
#> 3        adl-har-ucihar verified TRUE       
#> 4     adl-rasch-verbagg verified TRUE       
#> 5      adl-selfcare-hmp verified TRUE

The research queue

Some cases escalate an unresolved question to a paper. escalations() lists them (public cases keep this empty by embargo):

escalations()
#> [1] id       target   question
#> <0 rows> (or 0-length row.names)

Where to go next

  • ?list_cases / ?get_case – browse and open cases.
  • ?validate_cases – the invariants gate.
  • ?case_bundle – the on-disk evidence a reader re-runs or audits; the same bundle shape PhysioLake::physioPutBundle() stores with lineage.