trialdiff is a clinical-trial data-cut change detection and downstream
impact assessment framework for R, designed for the pharmaverse ecosystem.
Existing tools tell you that two datasets differ. trialdiff answers the
clinical-programming question that follows:
What changed, what does the change represent, and which downstream analyses or outputs might be affected?
It does this in five transparent, composable layers:
| Layer | Function | Purpose |
|---|---|---|
| Compare | compare_cut() |
Added/removed/modified observations and schema changes |
| Classify | classify_changes() |
Rule-based clinical change taxonomy |
| Trace | define_lineage(), trace_dependencies(), lineage_from_metadata(), output_registry() |
Explicit data lineage graph |
| Assess | assess_impact() |
Definitely / potentially / unlikely impact |
| Report | report_diff() |
HTML, Quarto and machine-readable JSON |
Everything is deterministic. There is no machine learning, and no statistical impact is ever claimed - analyses are flagged for review and rerun.
# From CRAN
install.packages("trialdiff")
# Development version from GitHub
# install.packages("remotes")
remotes::install_github("Hirujan-R/trialdiff")library(trialdiff)
diff <- compare_cut(
old = adsl_cut1,
new = adsl_cut2,
by = "USUBJID",
dataset = "ADSL"
)
classified <- classify_changes(diff)
impact <- assess_impact(classified, adsl_adlb_lineage)
report_diff(diff, impact = impact, output = "report.html")A treatment assignment change (TRT01P = "Placebo" -> "Drug A") is detected,
classified as a treatment-assignment change, traced through
ADSL.TRT01P -> ADLB.TRT01P -> lab summary -> MMRM -> efficacy table, and every
downstream object is flagged for review with a rationale.
diffdf (and waldo) are excellent low-level comparison tools, and
trialdiff deliberately does not reinvent them. trialdiff adds the layers
that are specific to clinical programming:
- a clinical change taxonomy (new subject, new visit, corrected value, missingness transitions, derived-variable change, treatment-assignment change, metadata change, ...);
- explicit lineage between datasets, variables, analyses and outputs;
- auditable impact assessment with a documented policy;
- review reports that name the objects a programmer or statistician must check.
It can even delegate the low-level comparison itself: compare_cut(..., backend = "diffdf") uses diffdf to detect differences and translates the
result into the same tdiff object.
- Deterministic comparison, not opaque inference.
- Transparent, user-extensible rules.
- Explicit, reproducible lineage metadata.
- Auditable impact assessment with a written rationale for every flag.
- Clinically meaningful reporting.
vignette("trialdiff")- getting started.vignette("change-classification")- the rule system.vignette("lineage-and-impact")- lineage and impact.vignette("ecosystem")- relationship todiffdf,admiral,metacore,cards,tern, SASPROC COMPAREand others.vignette("case-study")- end-to-end walkthrough on publicpharmaverseadamdata.
A full proposal covering the problem statement, ecosystem/gap analysis, novelty assessment, architecture, testing and roadmap is available in the project proposal.
Please note that the trialdiff project is released with a
Contributor Code of Conduct.
By contributing you agree to abide by its terms.
MIT (c) Hirujan Rangaraj. No proprietary or real patient data is included; all example datasets are synthetic.