Writes a cpsdrft() result to a single web page for a reader
who will
not run R. Everything is inside the file: the stylesheet, a short script,
and the binned summaries of each column as JSON. Nothing is fetched, so
the page opens from disk (file://) and looks the same later.
Arguments
- x
A
cpsdrft()result. Attach a provenance record asx$provenance(for example fromloadprov()) and anmnfdiff()asx$manifestto show them;rmbl drift --htmldoes both.- file
The path to write.
- title
The page title, a string.
- warn, fail
The PSI bands the page opens with;
NULL(the default) takes the object'sbands.- open
Logical: open the page in the browser when written (default
FALSE).
Details
The page shows:
a header with the overall verdict, the count of columns per verdict, the row counts, when the page was written, the package version, and the capsule's provenance (name, source, pinned SHA-256, data date) when
x$provenanceholds one;a hero canvas: the chosen column's reference and current distributions as ribbons, the band between them shaded, drawn in on load and on each new column (still when the reader asks for reduced motion);
Columns: the table (verdict, column, type, test: KS for numbers and dates, chi-square homogeneity for categories; statistic, p-value, PSI, the change in the missing share and both sample sizes) with a search box, filters by verdict and type and sorting on any header; and the column detail for the column chosen (click a row, or the up and down keys;
/goes to the search box): both samples' summary statistics (dates in ISO 8601) or the ten largest categories, a sentence on the verdict, and charts each with a line on how to read it: the density overlay with the area between shaded (numeric) or the category flow from reference to current shares (categorical), the ECDF overlay with the largest gap marked, the quantile shift against the identity line (numeric), the PSI by bin, drawn up where the current sample has more mass, and the first digits against Benford's law with its 95% band (numeric);Overview: the drift fingerprint, one spoke per column at its PSI with the warn and fail bands as rings, and a tile per column with its two distributions in small;
Manifest, when
x$manifestholds anmnfdiff(): the resources before and after as a tree, and the table of digests and sizes;History: pick earlier
rmbl drift --jsonoutputs or this page's JSON exports, and the PSI of each column over the runs is drawn as a heatmap in the bands, the first crossing of the fail band outlined, and as a line per column;Capsule chain: provenance, pinned bytes, manifest and attestation, each verified, moved, failed or not checked (from the capsule's checks when
rmbl driftmade the report);sliders for the warn and fail PSI bands and for alpha, which score every verdict and chart again as they move, and a button back to the object's bands;
exports: Markdown, JSON, each chart as SVG, and the column table copied as a GitHub comment.
Every chart is drawn at its card's width, two to a row on a wide screen
and one on a narrow one, in the colours of the theme in use.
The verdicts: fail when the test rejects at alpha, or the PSI is above
the fail band with both samples at least psiminn; warn when the PSI
is above the warn band; untested when no test applies; ok otherwise.
At the object's bands fail is cpsdrft()'s
drifted. Each verdict is
written in words beside its symbol, the tables have header cells, and
each chart has a text label. A light or dark theme follows the system
and a button switches it. Every value is escaped. The page holds no rows
of the data, only the summaries in x$summ, so its size grows with the
number of columns and categories, not of rows.
Errors: x not from cpsdrft(); file not one
path; title not one
string; warn above fail.
Examples
set.seed(5)
ref <- data.frame(value = stats::rnorm(400),
grade = sample(c("a", "b", "c"), 400, TRUE))
cur <- data.frame(value = stats::rnorm(400, 0.4),
grade = sample(c("a", "b", "c"), 400, TRUE))
d <- cpsdrft(ref, cur)
f <- file.path(tempdir(), "drift.html")
drfthtml(d, f, title = "Pinned against fetched")
file.exists(f)
#> [1] TRUE
# narrower bands open the page with more columns to look at
drfthtml(d, f, warn = 0.02, fail = 0.05)
unlink(f)
try(drfthtml(list(), f))
#> Error : drfthtml: `x` must be a bricklayer_drift object from cpsdrft()
