R Under development (unstable) (2026-09-16 r90549) -- "Unsuffered Consequences" Copyright (C) 2026 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. Natural language support but running in an English locale R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > pkgname <- "rmoriebricklayer" > source(file.path(R.home("share"), "R", "examples-header.R")) > options(warn = 1) > library('rmoriebricklayer') > > base::assign(".oldSearch", base::search(), pos = 'CheckExEnv') > base::assign(".old_wd", base::getwd(), pos = 'CheckExEnv') > cleanEx() > nameEx("admissions") > ### * admissions > > flush(stderr()); flush(stdout()) > > ### Name: admissions > ### Title: Admissions implied by a population and a length of stay > ### Aliases: admissions > > ### ** Examples > > # Lakner (p.20) runs this the other way: t = 365, an average daily > # population of 25 and 1,750 admissions imply a stay of 5.2 days. > alos_implied <- 25 * 365 / 1750 > round(alos_implied, 1) [1] 5.2 > > # and back again > admissions(25, alos_implied) [1] 1750 > > > > cleanEx() > nameEx("adp") > ### * adp > > flush(stderr()); flush(stdout()) > > ### Name: adp > ### Title: Average daily population > ### Aliases: adp > > ### ** Examples > > # Lakner's own worked example (p.15): 3,000 inmates served 13,500 > # detention days in a year. > adp(13500) [1] 36.9863 > > # per-person days give the same total > adp(c(10, 20, 30), t = 30) [1] 2 > > > > cleanEx() > nameEx("adp_from_counts") > ### * adp_from_counts > > flush(stderr()); flush(stdout()) > > ### Name: adp_from_counts > ### Title: Person-days estimated from periodic headcounts > ### Aliases: adp_from_counts > > ### ** Examples > > # Lakner (p.21): counts on 255 days summing to 34,935 imply just over > # fifty thousand detention days across the year. > adp_from_counts(rep(34935 / 255, 255)) [1] 50005 > > > > cleanEx() > nameEx("agent_bundle") > ### * agent_bundle > > flush(stderr()); flush(stdout()) > > ### Name: agent_bundle > ### Title: Agent-assisted reproducibility-bundle help > ### Aliases: agent_bundle > > ### ** Examples > > > # With no rmorie binary on PATH the call returns an install hint, not an > # error -- safe to run anywhere: > if (!nzchar(Sys.which("rmorie"))) agent_bundle("hello") [1] "rmorie CLI not found on PATH. Install rmorie-cli to use agent_bundle()." > > > > cleanEx() > nameEx("alos") > ### * alos > > flush(stderr()); flush(stdout()) > > ### Name: alos > ### Title: Average length of stay > ### Aliases: alos > > ### ** Examples > > # Lakner (p.17): 2,700 inmates admitted and released served 12,150 > # detention days between them. > alos(12150, 2700) [1] 4.5 > > > > cleanEx() > nameEx("apply_schema_validation") > ### * apply_schema_validation > > flush(stderr()); flush(stdout()) > > ### Name: apply_schema_validation > ### Title: Apply Schema Validation, Stopping on Fatal Issues > ### Aliases: apply_schema_validation > > ### ** Examples > > prov <- list(schema = list(expected_columns = "id")) > apply_schema_validation(data.frame(id = 1), prov) > # A missing required column is fatal: > try(apply_schema_validation(data.frame(x = 1), prov)) Error : Missing required columns: id > > > > cleanEx() > nameEx("ascii_fallback") > ### * ascii_fallback > > flush(stderr()); flush(stdout()) > > ### Name: ascii_fallback > ### Title: Use Text As-Is, Falling Back to ASCII When It Cannot Be > ### Represented > ### Aliases: ascii_fallback > > ### ** Examples > > # By default valid UTF-8 is preserved (accents kept where supported). > ascii_fallback("\u00c1ngela") # "\u00c1ngela" [1] "Ángela" > > # force = TRUE always transliterates (for ASCII-only destinations > # such as a package DESCRIPTION). > ascii_fallback("\u00c1ngela", force = TRUE) # "Angela" [1] "Angela" > > # Plain ASCII is returned unchanged either way. > ascii_fallback("plain name") [1] "plain name" > > # Vectorised; each element handled independently. > ascii_fallback(c("caf\u00e9", "resume"), force = TRUE) [1] "cafe" "resume" > > > > cleanEx() > nameEx("band_sensitivity") > ### * band_sensitivity > > flush(stderr()); flush(stdout()) > > ### Name: band_sensitivity > ### Title: How much a result depends on the open band's assumed cap > ### Aliases: band_sensitivity print.rmbl_band_sensitivity > > ### ** Examples > > b <- parse_bands(c("1", "2 to 5", "6 to 10", "Greater than 10")) > counts <- c(1200, 430, 110, 38) > > s <- band_sensitivity(b, counts) > s ── Sensitivity to the open top band's assumed cap ──────────────── cap value 11.55000 0.4254708 15.09841 0.4346095 19.73696 0.4461100 25.80058 0.4604302 33.72707 0.4780278 44.08875 0.4993060 57.63375 0.5245371 75.34008 0.5537719 98.48616 0.5867522 128.74322 0.6228545 168.29590 0.6610951 220.00000 0.7002144 span over the caps tried: 0.2747 (53.7% of the typical value) The statistic moves by more than a tenth of itself across the caps tried, so it is a property of the assumption as much as of the data. Report the range, not a single figure. ────────────────────────────────────────────────────────────────── > > # A statistic that barely moves has been measured; one that swings > # has not. > band_sensitivity(b, counts, statistic = mean) ── Sensitivity to the open top band's assumed cap ──────────────── cap value 11.55000 2.257283 15.09841 2.295202 19.73696 2.344771 25.80058 2.409567 33.72707 2.494271 44.08875 2.604998 57.63375 2.749742 75.34008 2.938955 98.48616 3.186298 128.74322 3.509629 168.29590 3.932296 220.00000 4.484814 span over the caps tried: 2.228 (83.2% of the typical value) The statistic moves by more than a tenth of itself across the caps tried, so it is a property of the assumption as much as of the data. Report the range, not a single figure. ────────────────────────────────────────────────────────────────── > > > > cleanEx() > nameEx("band_values") > ### * band_values > > flush(stderr()); flush(stdout()) > > ### Name: band_values > ### Title: Representative values for banded categories > ### Aliases: band_values > > ### ** Examples > > b <- parse_bands(c("1", "2 to 5", "6 to 10", "Greater than 10")) > > band_values(b) label lower upper open_lower open_upper value assumed 1 1 1 1 FALSE FALSE 1.0 FALSE 2 2 to 5 2 5 FALSE FALSE 3.5 FALSE 3 6 to 10 6 10 FALSE FALSE 8.0 FALSE 4 Greater than 10 11 NA FALSE TRUE 16.5 TRUE > > # The lower and upper rules bracket the truth. > band_values(b, rule = "lower")$value [1] 1 2 6 11 > band_values(b, rule = "upper", open_upper_cap = 40)$value [1] 1 5 10 40 > > > > cleanEx() > nameEx("benford_test") > ### * benford_test > > flush(stderr()); flush(stdout()) > > ### Name: benford_test > ### Title: Benford first-digit test > ### Aliases: benford_test > > ### ** Examples > > # A quantity spanning several orders of magnitude follows the law. > set.seed(3) > benford_test(10^stats::runif(2000, 0, 6)) ── Benford first-digit screen ──────────────────────────────────── ✓ consistent with Benford's law values used 2,000 chi-square 10.073 df 8 p-value 0.26 digit observed expected shape 1 0.298 0.301 #################### 2 0.169 0.176 ########### 3 0.126 0.125 ######## 4 0.092 0.097 ###### 5 0.073 0.079 ##### 6 0.072 0.067 ##### 7 0.054 0.058 #### 8 0.060 0.051 #### 9 0.055 0.046 #### ────────────────────────────────────────────────────────────────── > > # Digits drawn uniformly do not. > benford_test(as.numeric(paste0(sample(1:9, 2000, TRUE), "000"))) ── Benford first-digit screen ──────────────────────────────────── ! departs from Benford's law (screen only, not a verdict) values used 2,000 chi-square 769.038 df 8 p-value <2e-16 digit observed expected shape 1 0.106 0.301 ################# 2 0.123 0.176 #################### 3 0.123 0.125 #################### 4 0.112 0.097 ################## 5 0.103 0.079 ################# 6 0.102 0.067 ################# 7 0.099 0.058 ################ 8 0.119 0.051 ################### 9 0.112 0.046 ################## ────────────────────────────────────────────────────────────────── > > # The expected proportions are the closed form. > b <- benford_test(10^stats::runif(500, 0, 5)) > all.equal(b$expected / b$n, log10(1 + 1 / (1:9))) [1] "names for target but not for current" > > # Zeros carry no leading digit and are excluded from n. > benford_test(c(0, 0, 1, 2, 3))$n [1] 3 > > > > cleanEx() > nameEx("bricklayer_fetch") > ### * bricklayer_fetch > > flush(stderr()); flush(stdout()) > > ### Name: bricklayer_fetch > ### Title: Fetch a URL to disk with an Internet Archive fallback > ### (C++/libcurl) > ### Aliases: bricklayer_fetch > > ### ** Examples > > # Inputs are validated before any network access: > try(bricklayer_fetch("", tempfile())) # empty url -> error Error in bricklayer_fetch("", tempfile()) : nzchar(url) is not TRUE > > > > > cleanEx() > nameEx("bricklayer_fetch_parse_siu") > ### * bricklayer_fetch_parse_siu > > flush(stderr()); flush(stdout()) > > ### Name: bricklayer_fetch_parse_siu > ### Title: Fetch and parse one SIU director's report > ### Aliases: bricklayer_fetch_parse_siu > > ### ** Examples > > > > > cleanEx() > nameEx("bricklayer_fetch_siu") > ### * bricklayer_fetch_siu > > flush(stderr()); flush(stdout()) > > ### Name: bricklayer_fetch_siu > ### Title: Fetch an Ontario SIU director's report by drid > ### Aliases: bricklayer_fetch_siu > > ### ** Examples > > > > > cleanEx() > nameEx("bricklayer_json_from_json") > ### * bricklayer_json_from_json > > flush(stderr()); flush(stdout()) > > ### Name: bricklayer_json_from_json > ### Title: Parse JSON into R objects (jsonlite's fromJSON, natively) > ### Aliases: bricklayer_json_from_json > > ### ** Examples > > bricklayer_json_from_json('[{"a":1,"b":"x"},{"a":2,"b":"y"}]') a b 1 1 x 2 2 y > bricklayer_json_from_json('[[1,2],[3,4]]') [,1] [,2] [1,] 1 2 [2,] 3 4 > > > > cleanEx() > nameEx("bricklayer_json_to_json") > ### * bricklayer_json_to_json > > flush(stderr()); flush(stdout()) > > ### Name: bricklayer_json_to_json > ### Title: Encode an R object as JSON (jsonlite's toJSON, natively) > ### Aliases: bricklayer_json_to_json > > ### ** Examples > > bricklayer_json_to_json(list(a = 1:3, b = "x"), auto_unbox = TRUE) [1] "{\"a\":[1,2,3],\"b\":\"x\"}" attr(,"class") [1] "json" > bricklayer_json_to_json(data.frame(id = 1:2, v = c(1.5, NA)), pretty = TRUE) [1] "[\n {\n \"id\": 1,\n \"v\": 1.5\n },\n {\n \"id\": 2\n }\n]" attr(,"class") [1] "json" > > > > cleanEx() > nameEx("bricklayer_parse_siu") > ### * bricklayer_parse_siu > > flush(stderr()); flush(stdout()) > > ### Name: bricklayer_parse_siu > ### Title: Parse an SIU director's report into the schema fields > ### Aliases: bricklayer_parse_siu > > ### ** Examples > > f <- bricklayer_parse_siu(system.file("extdata", + "siu_synthetic_report.html", + package = "rmoriebricklayer")) > f[["number_of_subject_officers"]] [1] "2" > > > > cleanEx() > nameEx("bricklayer_siu_iso_date") > ### * bricklayer_siu_iso_date > > flush(stderr()); flush(stdout()) > > ### Name: bricklayer_siu_iso_date > ### Title: Convert a human-readable SIU report date to ISO format > ### Aliases: bricklayer_siu_iso_date > > ### ** Examples > > bricklayer_siu_iso_date(c("January 5, 2023", "not a date")) [1] "2023-01-05" "" > > > > cleanEx() > nameEx("bricklayer_siu_resolve_so") > ### * bricklayer_siu_resolve_so > > flush(stderr()); flush(stdout()) > > ### Name: bricklayer_siu_resolve_so > ### Title: Resolve the subject-official count from SIU report text > ### Aliases: bricklayer_siu_resolve_so > > ### ** Examples > > bricklayer_siu_resolve_so( + "Subject Officials\nSO #1 Interviewed\nSO #2 Declined interview") $count [1] 2 $reason [1] "section: max(ordinal 2, entries 2)" > > > > cleanEx() > nameEx("bricklayer_siu_schema") > ### * bricklayer_siu_schema > > flush(stderr()); flush(stdout()) > > ### Name: bricklayer_siu_schema > ### Title: The panel-reviewed SIU report field schema > ### Aliases: bricklayer_siu_schema > > ### ** Examples > > bricklayer_siu_schema() name is_count 1 police_service FALSE 2 date_of_incident_iso FALSE 3 date_siu_notified_iso FALSE 4 date_of_director_decision_iso FALSE 5 siu_investigators TRUE 6 siu_forensics_investigators TRUE 7 number_of_witness_officials TRUE 8 number_of_civilian_witnesses TRUE 9 number_of_subject_officers TRUE 10 age_affected FALSE 11 sex_gender_affected FALSE 12 charges_recommended FALSE 13 directors_name FALSE 14 location_of_call FALSE 15 specific_injuries FALSE 16 relevant_legislation FALSE description 1 the police service(s) whose officials the SIU investigated 2 the date the incident occurred (ISO YYYY-MM-DD) 3 the date the SIU was notified/invoked (ISO YYYY-MM-DD) 4 the date of the Director's decision (ISO YYYY-MM-DD) 5 the number of SIU investigators assigned 6 the number of SIU forensic investigators assigned 7 the count of distinct WITNESS officers/officials (WO) 8 the count of distinct civilian witnesses (CW) 9 the count of distinct SUBJECT officers/officials (SO); a witness-officer-only investigation is 0 10 the age (or age range) of the affected person/complainant 11 the sex/gender of the affected person/complainant 12 whether charges were recommended/laid, and against whom 13 the name of the SIU Director who decided 14 the location/address where the incident occurred 15 the specific injuries the affected person sustained 16 the legislation/Criminal Code sections the Director analysed > > > > cleanEx() > nameEx("bricklayer_siu_text") > ### * bricklayer_siu_text > > flush(stderr()); flush(stdout()) > > ### Name: bricklayer_siu_text > ### Title: Convert SIU report HTML to plain text > ### Aliases: bricklayer_siu_text > > ### ** Examples > > bricklayer_siu_text("
Number of SIU Investigators assigned: 3
") [1] " Number of SIU Investigators assigned: 3\n" > > > > cleanEx() > nameEx("capsule_attest") > ### * capsule_attest > > flush(stderr()); flush(stdout()) > > ### Name: capsule_attest > ### Title: Attest a capsule, binding a signature to what it covers > ### Aliases: capsule_attest capsule_check_attestation > > ### ** Examples > > m <- make_manifest(list(dataset = "otis", rows = 1200L), + environment = FALSE) > key <- fips_keygen("ML-DSA-65") > att <- capsule_attest(m, key, note = "counts as published") > > # a verifier needs the attestation and the manifest, nothing else > res <- capsule_check_attestation(att, m) > res$ok [1] TRUE > res$checks check ok 1 attestation_complete TRUE 2 manifest_digest TRUE 3 signature TRUE detail 1 2 efa1b7387f225380245de0b5170999e87ad4044f3e8fd2ef6a6bfbc2bd0a9c90 3 > > # any change to the manifest breaks it > m2 <- m > m2$meta$rows <- 1201L > capsule_check_attestation(att, m2)$ok [1] FALSE > > # and so does presenting a different key > capsule_check_attestation(att, m, + key_expected = fips_keygen("ML-DSA-65")$public)$ok [1] FALSE > > > > cleanEx() > nameEx("capsule_bundle") > ### * capsule_bundle > > flush(stderr()); flush(stdout()) > > ### Name: capsule_bundle > ### Title: Bundle a capsule into one signed artifact > ### Aliases: capsule_bundle capsule_bundle_read capsule_bundle_verify > > ### ** Examples > > dir <- tempfile() > dir.create(dir) > write.csv(data.frame(x = 1:3), file.path(dir, "data.csv"), + row.names = FALSE) > m <- make_manifest(list(dataset = "demo"), environment = FALSE) > key <- fips_keygen("ML-DSA-44") > > b <- capsule_bundle(dir, m, key, note = "as published") > capsule_bundle_verify(attr(b, "path"), dir, manifest = m)$ok [1] TRUE > > # touch a byte of the data and the bundle no longer holds > write.csv(data.frame(x = 1:4), file.path(dir, "data.csv"), + row.names = FALSE) > capsule_bundle_verify(attr(b, "path"), dir, manifest = m)$ok [1] FALSE > unlink(dir, recursive = TRUE) > > > > cleanEx() > nameEx("capsule_drift") > ### * capsule_drift > > flush(stderr()); flush(stdout()) > > ### Name: capsule_drift > ### Title: Compare a fetched data frame with the one a capsule was pinned > ### against > ### Aliases: capsule_drift > > ### ** Examples > > set.seed(5) > ref <- data.frame( + value = stats::rnorm(300), + size = stats::runif(300, 1, 10), + grade = sample(c("a", "b", "c"), 300, TRUE) + ) > > # A fresh draw from the same process: no drift. > same <- data.frame( + value = stats::rnorm(300), + size = stats::runif(300, 1, 10), + grade = sample(c("a", "b", "c"), 300, TRUE) + ) > d <- capsule_drift(ref, same) > d$any_drift [1] FALSE > > # A silently rescaled column, and a new category, are both caught. > moved <- same > moved$size <- moved$size * 3 > moved$grade[1:100] <- "z" > capsule_drift(ref, moved) ── Capsule drift report ────────────────────────────────────────── ✗ DRIFT DETECTED reference rows 300 current rows 300 columns tested 3 alpha 0.01 ── Per-column tests ────────────────────────────────────────────── column type stat p psi ✗ grade categorical 121 <2e-16 – ✗ size numeric 0.743 <2e-16 4.299 ✓ value numeric 0.05 0.847 0.092 ────────────────────────────────────────────────────────────────── > > # The PSI is always reported as an effect size, but on a sample this > # small it is not allowed to raise the flag by itself -- binning noise > # alone would clear 0.25. Lower psi_min_n to override that. > capsule_drift(ref, same)$columns$psi [1] 0.09244204 0.06635985 NA > > # Structural changes are reported rather than tested. > capsule_drift(ref, same[, c("value", "grade")])$removed [1] "size" > > > > cleanEx() > nameEx("capsule_falsify") > ### * capsule_falsify > > flush(stderr()); flush(stdout()) > > ### Name: capsule_falsify > ### Title: Run falsification controls against a statistic > ### Aliases: capsule_falsify > > ### ** Examples > > set.seed(1) > d <- data.frame(x = rnorm(200)) > d$y <- 0.8 * d$x + rnorm(200) > # a real association survives its controls > real <- capsule_falsify(d, function(z) cor(z$x, z$y), + treatment = "x", n = 199, seed = 42) > real$controls[, c("control", "passed")] control passed 1 permutation TRUE 2 placebo TRUE 3 random_common_cause TRUE 4 subset_stability TRUE > > # and a statistic that ignores the data fails the ones that can see it > fake <- capsule_falsify(d, function(z) 0.5, treatment = "x", + n = 199, seed = 42) > fake$controls[fake$controls$control == "permutation", "passed"] [1] FALSE > > > > cleanEx() > nameEx("capsule_power") > ### * capsule_power > > flush(stderr()); flush(stdout()) > > ### Name: capsule_power > ### Title: Detect an injected effect of known size > ### Aliases: capsule_power > > ### ** Examples > > set.seed(1) > d <- data.frame(x = rnorm(120), y = rnorm(120)) > # inject a linear effect of x on y > inj <- function(z, size) { + z$y <- z$y + size * z$x + z + } > pw <- capsule_power(d, function(z) cor(z$x, z$y), inj, + sizes = c(0, 0.3, 0.6), treatment = "x", + n = 99, reps = 5, seed = 42) > pw$curve size detected reps rate 1 0.0 0 5 0 2 0.3 5 5 1 3 0.6 5 5 1 > > # The rate at size 0 estimates the false-positive rate. With few > # repetitions it is usually 0, because alpha is small -- five draws > # at 0.05 come up empty about three times in four -- so read it as a > # sanity check that it is not LARGE, not as an estimate of alpha. > pw$curve[pw$curve$size == 0, "rate"] [1] 0 > > > > cleanEx() > nameEx("capsule_report") > ### * capsule_report > > flush(stderr()); flush(stdout()) > > ### Name: capsule_report > ### Title: Assess a capsule in one call > ### Aliases: capsule_report > > ### ** Examples > > set.seed(1) > ref <- data.frame( + id = 1:200, + score = stats::runif(200, 0, 10), + grade = sample(c("a", "b", "c"), 200, TRUE), + stringsAsFactors = FALSE + ) > > # A fresh extract from the same process: nothing to report. > cur <- ref > cur$score <- stats::runif(200, 0, 10) > capsule_report(cur, reference = ref, schema = infer_schema(ref)) ── Capsule report ──────────────────────────────────────────────── ✓ these checks found nothing rows 200 columns 3 missing cells 0.0% complete rows 100.0% digest e1cbf9a9949ba4eed8e386aea8a43d6a No finding is proof of correctness: each check has a stated blind spot, and a small sample has little power. ────────────────────────────────────────────────────────────────── > > # One rescaled column and a new category: both surface, worst first. > bad <- cur > bad$score <- bad$score * 5 > bad$grade[1:80] <- "z" > r <- capsule_report(bad, reference = ref, schema = infer_schema(ref)) > r ── Capsule report ──────────────────────────────────────────────── ✗ WARNINGS: something moved rows 200 columns 3 missing cells 0.0% complete rows 100.0% digest 7510d7d7b267d81f4f26ea389443f4dc ── Findings (4) ────────────────────────────────────────────────── ✗ warn drift grade categorical test, p = <2e-16 ✗ warn drift score numeric test, p = <2e-16 ✗ warn schema range_score Column 'score' has 161 value(s) outside [-0.8488307, 10.90645] ✗ warn schema unexpected_grade Column 'grade' has unexpected values: z ────────────────────────────────────────────────────────────────── > r$verdict [1] "warn" > r$findings[, c("severity", "check", "subject")] severity check subject 1 warn drift grade 2 warn drift score 3 warn schema range_score 4 warn schema unexpected_grade > > # A missing column is fatal, because nothing downstream can run. > capsule_report(bad[, c("id", "score")], reference = ref, + schema = infer_schema(ref))$verdict [1] "fatal" > > > > cleanEx() > nameEx("capsule_sign") > ### * capsule_sign > > flush(stderr()); flush(stdout()) > > ### Name: capsule_sign > ### Title: Sign a capsule manifest > ### Aliases: capsule_sign > > ### ** Examples > > # Symmetric: one shared secret. > sig <- capsule_sign("sha256:abc123", key = "shared-secret", + scheme = "hmac") > capsule_verify("sha256:abc123", sig, "shared-secret") [1] TRUE > capsule_verify("sha256:TAMPERED", sig, "shared-secret") [1] FALSE > > # Post-quantum: the verifier needs only the public root. > key <- pqc_keygen(height = 2) > s1 <- capsule_sign("manifest-1", key) > capsule_verify("manifest-1", s1, signing_public_key(key)) [1] TRUE > > # Carry the advanced key state forward for the next signature. > key <- s1$key_state > key$next_index [1] 1 > s2 <- capsule_sign("manifest-2", key) > capsule_verify("manifest-2", s2, signing_public_key(key)) [1] TRUE > > # A signature does not transfer to another message. > capsule_verify("manifest-1", s2, signing_public_key(key)) [1] FALSE > > > > cleanEx() > nameEx("capsule_verify") > ### * capsule_verify > > flush(stderr()); flush(stdout()) > > ### Name: capsule_verify > ### Title: Verify a capsule manifest signature > ### Aliases: capsule_verify > > ### ** Examples > > key <- pqc_keygen(height = 2) > sig <- capsule_sign("pinned-manifest", key) > pub <- signing_public_key(key) > > capsule_verify("pinned-manifest", sig, pub) [1] TRUE > > # Every way of being wrong returns FALSE. > capsule_verify("edited-manifest", sig, pub) # message changed [1] FALSE > bad <- sig; bad$signature <- paste0("ff", substring(bad$signature, 3)) > capsule_verify("pinned-manifest", bad, pub) # signature edited [1] FALSE > capsule_verify("pinned-manifest", sig, + signing_public_key(pqc_keygen(height = 2))) # foreign key [1] FALSE > > # A truncated signature is not verified, and does not error. > trunc <- sig; trunc$signature <- substring(sig$signature, 1, 64) > capsule_verify("pinned-manifest", trunc, pub) [1] FALSE > > > > cleanEx() > nameEx("capture_dependencies") > ### * capture_dependencies > > flush(stderr()); flush(stdout()) > > ### Name: capture_dependencies > ### Title: Where each loaded package came from > ### Aliases: capture_dependencies > > ### ** Examples > > deps <- capture_dependencies(c("stats", "utils")) > deps[, c("package", "version")] package version 1 stats 4.7.0 2 utils 4.7.0 > > # a package with no repository field records that fact > is.na(capture_dependencies("stats")$repository) [1] TRUE > > > > cleanEx() > nameEx("capture_environment") > ### * capture_environment > > flush(stderr()); flush(stdout()) > > ### Name: capture_environment > ### Title: Capture the Analysis Environment for a Manifest > ### Aliases: capture_environment > > ### ** Examples > > # Record specific packages' versions alongside the session facts. > env <- capture_environment(c("stats", "utils")) > env$r_version [1] "4.7.0" > env$os [1] "Linux 7.1.3-200.fc44.x86_64" > env$packages # named character vector of versions stats utils "4.7.0" "4.7.0" > > # Default captures every currently loaded namespace. > names(capture_environment())[1:4] [1] "r_version" "platform" "os" "captured_utc" > > > > cleanEx() > nameEx("cert_chain_verify") > ### * cert_chain_verify > > flush(stderr()); flush(stdout()) > > ### Name: cert_chain_verify > ### Title: Verify a certificate chain > ### Aliases: cert_chain_verify > > ### ** Examples > > ## Not run: > ##D res <- cert_chain_verify("tsa.crt", trust = "ca.crt", > ##D purpose = "timeStamping") > ##D res$ok > ##D res$checks > ## End(Not run) > > > > cleanEx() > nameEx("cert_parse") > ### * cert_parse > > flush(stderr()); flush(stdout()) > > ### Name: cert_parse > ### Title: Parse an X.509 certificate > ### Aliases: cert_parse > > ### ** Examples > > # Certificates come from outside the package, so there is nothing to > # parse offline; this is the shape of the call. > ## Not run: > ##D cert <- cert_parse("tsa.crt") > ##D cert$subject > ##D cert$not_after > ##D cert$extended_key_usage > ## End(Not run) > > > > cleanEx() > nameEx("chunk_file") > ### * chunk_file > > flush(stderr()); flush(stdout()) > > ### Name: chunk_file > ### Title: Split a file into fixed-size chunks > ### Aliases: chunk_file > > ### ** Examples > > p <- tempfile() > writeLines(rep("some capsule content", 50), p) > > # One small chunk size to show the splitting. > ch <- chunk_file(p, chunk_bytes = 128) > length(ch) [1] 9 > > # The chunks reconstruct the file and pin it as a Merkle root. > merkle_root(ch) [1] "c4cb691d88a0dbf1dad9767c19095d54ac6958e6411e06d81dced0dba895c382" > > # They are the file's bytes, so they concatenate back to it exactly. > identical(unlist(ch), readBin(p, "raw", file.size(p))) [1] TRUE > > # Editing the file changes exactly one leaf. > unlink(p) > > > > cleanEx() > nameEx("cite_capsule") > ### * cite_capsule > > flush(stderr()); flush(stdout()) > > ### Name: cite_capsule > ### Title: Generate a Data Citation From Provenance > ### Aliases: cite_capsule > > ### ** Examples > > prov <- list( + captured_at_utc = "2026-06-23T04:41:40Z", + dataset = list(publisher = "Ontario Ministry of the Solicitor General", + licence_short = "OGL-Ontario", + package_slug = "data-on-inmates-in-ontario"), + resource = list(name = "Restrictive Confinement - Detailed Dataset", + direct_url = "https://data.ontario.ca/example.csv") + ) > cit <- cite_capsule(prov) > > # Plain-text citation ready to paste. > cat(cit$text) Ontario Ministry of the Solicitor General (2026). Restrictive Confinement - Detailed Dataset [Data set]. https://data.ontario.ca/example.csv Retrieved 2026-06-23. Licence: OGL-Ontario.> > # BibTeX @misc entry for LaTeX bibliographies. > cat(cit$bibtex) @misc{dataoninmatesinontario2026, author = {{Ontario Ministry of the Solicitor General}}, title = {Restrictive Confinement - Detailed Dataset}, year = {2026}, url = {https://data.ontario.ca/example.csv}, note = {Retrieved 2026-06-23; licence: OGL-Ontario}, }> > # NULL provenance returns NULL (composes safely). > cite_capsule(NULL) NULL > > > > cleanEx() > nameEx("clean_column_names") > ### * clean_column_names > > flush(stderr()); flush(stdout()) > > ### Name: clean_column_names > ### Title: Tidy the column names of an ingested table > ### Aliases: clean_column_names > > ### ** Examples > > clean_column_names(c("Total Population (2021)", "% change", + "Ville / City", "dup", "dup")) [1] "total_population_2021" "pct_change" "ville_city" [4] "dup" "dup_2" > > # Applied to a data frame, with the original names retained. > df <- data.frame(`Total Pop` = 1:2, `% change` = 3:4, + check.names = FALSE) > cleaned <- clean_column_names(df) > names(cleaned) [1] "total_pop" "pct_change" > attr(cleaned, "original_names") [1] "Total Pop" "% change" > > # Other cases. > clean_column_names(c("Total Pop"), case = "lower_camel") [1] "totalPop" > clean_column_names(c("Total Pop"), case = "upper_camel") [1] "TotalPop" > clean_column_names(c("Total Pop"), case = "screaming_snake") [1] "TOTAL_POP" > > > > cleanEx() > nameEx("concentration") > ### * concentration > > flush(stderr()); flush(stdout()) > > ### Name: concentration > ### Title: Concentration of a total across units > ### Aliases: concentration gini lorenz top_share > > ### ** Examples > > # Ten units holding one each: no concentration. > gini(rep(1, 10)) [1] 0 > > # One unit holding everything: the maximum for ten units. > gini(c(rep(0, 9), 1)) [1] 0.9 > 1 - 1 / 10 [1] 0.9 > > placements <- c(rep(1, 1200), rep(3, 430), rep(8, 110), rep(20, 38)) > gini(placements) [1] 0.461225 > > # What the most frequent few account for. > top_share(placements, c(0.01, 0.05, 0.1)) fraction units share 1 0.01 18 0.08716707 2 0.05 89 0.28280872 3 0.10 178 0.41888620 > > head(lorenz(placements)) population value 1 0.0000000000 0.0000000000 2 0.0005624297 0.0002421308 3 0.0011248594 0.0004842615 4 0.0016872891 0.0007263923 5 0.0022497188 0.0009685230 6 0.0028121485 0.0012106538 > > > > cleanEx() > nameEx("core_blake2b") > ### * core_blake2b > > flush(stderr()); flush(stdout()) > > ### Name: core_blake2b > ### Title: BLAKE2b digest, optionally keyed > ### Aliases: core_blake2b > > ### ** Examples > > # The RFC 7693 test vector for BLAKE2b-512 of "abc". > core_blake2b("abc", length = 64) [1] "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923" > > # 32 bytes by default, the same width as SHA-256. > core_blake2b("abc") [1] "bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319" > nchar(core_blake2b("abc")) [1] 64 > > # Any digest length, which SHA-2 cannot do. > core_blake2b("abc", length = 8) [1] "d8bb14d833d59559" > > # Keyed, so it authenticates without an HMAC construction. > core_blake2b("manifest", key = "secret") [1] "0fa448067a359db7f409a8de6a616a39d51393c32532bce014075308cbb1f222" > core_blake2b("manifest", key = "secret") == + core_blake2b("manifest", key = "other") [1] FALSE > > # Vectorised, and raw input hashes the same bytes. > core_blake2b(c("a", "b")) [1] "8928aae63c84d87ea098564d1e03ad813f107add474e56aedd286349c0c03ea4" [2] "6e5c1f45cbaf19f94230ba3501c378a5335af71a331b5b5aed62792332288dc3" > identical(core_blake2b("abc"), core_blake2b(charToRaw("abc"))) [1] TRUE > > > > cleanEx() > nameEx("core_bootstrap_mean") > ### * core_bootstrap_mean > > flush(stderr()); flush(stdout()) > > ### Name: core_bootstrap_mean > ### Title: Bootstrap replicate means (C backend) > ### Aliases: core_bootstrap_mean > > ### ** Examples > > set.seed(1) > x <- stats::rnorm(50, mean = 5) > > reps <- core_bootstrap_mean(x, B = 500, seed = 7) > length(reps) [1] 500 > > # The replicates centre on the sample mean, and their spread estimates > # the standard error. > c(sample = mean(x), bootstrap = mean(reps)) sample bootstrap 5.100448 5.097066 > c(bootstrap_se = stats::sd(reps), formula_se = stats::sd(x) / sqrt(length(x))) bootstrap_se formula_se 0.1174288 0.1175769 > > # A percentile confidence interval for the mean. > stats::quantile(reps, c(0.025, 0.975)) 2.5% 97.5% 4.864298 5.311439 > > # Reproducible: the same seed gives the same replicates, and R's own > # random stream is not consumed. > identical(core_bootstrap_mean(x, 100, seed = 1), + core_bootstrap_mean(x, 100, seed = 1)) [1] TRUE > > > > cleanEx() > nameEx("core_cov") > ### * core_cov > > flush(stderr()); flush(stdout()) > > ### Name: core_cov > ### Title: Covariance matrix of a numeric matrix (C backend) > ### Aliases: core_cov > > ### ** Examples > > X <- cbind(a = c(1, 2, 3, 4), b = c(2, 4, 7, 8), c = c(5, 3, 2, 1)) > core_cov(X) a b c a 1.666667 3.500000 -2.166667 b 3.500000 7.583333 -4.583333 c -2.166667 -4.583333 2.916667 > > # Agrees with stats::cov(). > all.equal(core_cov(X), stats::cov(X)) [1] TRUE > > # The diagonal is the column variances. > all.equal(diag(core_cov(X)), apply(X, 2, stats::var)) [1] TRUE > > # Data frames are accepted. > core_cov(data.frame(u = 1:5, v = c(2, 1, 4, 3, 6))) u v u 2.5 2.5 v 2.5 3.7 > > > > cleanEx() > nameEx("core_crc32") > ### * core_crc32 > > flush(stderr()); flush(stdout()) > > ### Name: core_crc32 > ### Title: CRC-32 checksum (C backend) > ### Aliases: core_crc32 > > ### ** Examples > > # The standard check value: CRC-32("123456789") is 0xCBF43926. > core_crc32("123456789") [1] 3421780262 > core_crc32("123456789") == 0xCBF43926 [1] TRUE > > # The empty input has checksum zero. > core_crc32("") [1] 0 > > # Vectorised, and sensitive to a single changed byte. > core_crc32(c("brick", "brack")) [1] 928041788 960731780 > > # Raw bytes work the same way. > core_crc32(charToRaw("123456789")) [1] 3421780262 > > > > cleanEx() > nameEx("core_gamma_cdf") > ### * core_gamma_cdf > > flush(stderr()); flush(stdout()) > > ### Name: core_gamma_cdf > ### Title: Regularized incomplete gamma function (C backend) > ### Aliases: core_gamma_cdf > > ### ** Examples > > core_gamma_cdf(3.5, c(0.5, 1, 4, 12)) [1] 0.005171463 0.040159631 0.667406097 0.998860649 > > # Identical to the unit-rate gamma CDF. > all.equal(core_gamma_cdf(3.5, c(0.5, 1, 4, 12)), + stats::pgamma(c(0.5, 1, 4, 12), shape = 3.5)) [1] TRUE > > # Shape 1 is the exponential distribution. > all.equal(core_gamma_cdf(1, c(0.5, 2)), stats::pexp(c(0.5, 2))) [1] TRUE > > # A chi-square tail on k degrees of freedom is 1 - P(k/2, q/2). > 1 - core_gamma_cdf(2 / 2, 5.99 / 2) # about 0.05 on 2 df [1] 0.05003663 > > > > cleanEx() > nameEx("core_hawkes_nll") > ### * core_hawkes_nll > > flush(stderr()); flush(stdout()) > > ### Name: core_hawkes_nll > ### Title: Hawkes-process negative log-likelihood (C backend) > ### Aliases: core_hawkes_nll > > ### ** Examples > > set.seed(4) > times <- sort(stats::runif(40, 0, 10)) > > # Exponential kernel: log-baseline -0.5, branching 0.3, decay 1.2. > core_hawkes_nll(times, 10, "exponential", c(-0.5, 0.3, 1.2)) [1] -1.8753 > > # Lower is better, so this is what an optimiser minimises. > nll <- function(p) core_hawkes_nll(times, 10, "exponential", p) > fit <- stats::optim(c(-0.5, 0.3, 1.2), nll) > fit$par [1] 1.03407757 0.99899989 0.08854609 > > # A branching ratio at or above 1 is not a stationary process, and is > # reported as the infeasible sentinel rather than a number. > core_hawkes_nll(times, 10, "exponential", c(-0.5, 1.5, 1.2)) == 1e12 [1] TRUE > > # The heavier-tailed kernels take two shape parameters. > core_hawkes_nll(times, 10, "gamma", c(-0.5, 0.3, 2, 1.5)) [1] -1.550628 > > > > cleanEx() > nameEx("core_ipw_weights") > ### * core_ipw_weights > > flush(stderr()); flush(stdout()) > > ### Name: core_ipw_weights > ### Title: Trimmed inverse-probability weights (C backend) > ### Aliases: core_ipw_weights > > ### ** Examples > > treat <- c(1, 0, 1, 0) > e <- c(0.5, 0.25, 0.02, 0.9) > > core_ipw_weights(treat, e) [1] 2.000000 1.333333 50.000000 10.000000 > > # A balanced score gives weight 2 to either arm. > core_ipw_weights(c(1, 0), c(0.5, 0.5)) [1] 2 2 > > # Without trimming the third observation would carry weight 50; the > # default clamp holds it to 100 at the 0.01 floor, and a looser floor > # tames it further. > core_ipw_weights(treat, e, trim_lo = 0.10) [1] 2.000000 1.333333 10.000000 10.000000 > > # Logical treatment indicators work too. > core_ipw_weights(c(TRUE, FALSE), c(0.4, 0.4)) [1] 2.500000 1.666667 > > > > cleanEx() > nameEx("core_moments") > ### * core_moments > > flush(stderr()); flush(stdout()) > > ### Name: core_moments > ### Title: Mean, variance, skewness and kurtosis in one pass (C backend) > ### Aliases: core_moments > > ### ** Examples > > core_moments(c(2, 4, 4, 4, 5, 5, 7, 9)) mean variance skewness kurtosis 5.000000 4.571429 0.656250 -0.218750 > > # The first two entries agree with base R. > m <- core_moments(1:10) > all.equal(m[["mean"]], mean(1:10)) [1] TRUE > all.equal(m[["variance"]], stats::var(1:10)) [1] TRUE > > # A symmetric sample has no skew; excess kurtosis is near 0 for normal > # data and positive for a heavy-tailed sample. > core_moments(c(-2, -1, 0, 1, 2))[["skewness"]] [1] 0 > core_moments(c(rep(0, 20), -8, 8))[["kurtosis"]] > 0 [1] TRUE > > # Too short to define a shape statistic: NaN rather than a guess. > core_moments(c(1, 2)) mean variance skewness kurtosis 1.5 0.5 NaN NaN > > > > cleanEx() > nameEx("core_normal_logpdf") > ### * core_normal_logpdf > > flush(stderr()); flush(stdout()) > > ### Name: core_normal_logpdf > ### Title: Normal log-density (C backend) > ### Aliases: core_normal_logpdf > > ### ** Examples > > core_normal_logpdf(c(-1, 0, 1)) [1] -1.4189385 -0.9189385 -1.4189385 > > # Identical to stats::dnorm(log = TRUE). > all.equal(core_normal_logpdf(-2:2, 0.3, 1.7), + stats::dnorm(-2:2, 0.3, 1.7, log = TRUE)) [1] TRUE > > # Still finite where the density itself underflows to zero. > stats::dnorm(50) # 0 [1] 0 > core_normal_logpdf(50) # about -1251 [1] -1250.919 > > > > cleanEx() > nameEx("core_normal_pdf") > ### * core_normal_pdf > > flush(stderr()); flush(stdout()) > > ### Name: core_normal_pdf > ### Title: Normal density (C backend) > ### Aliases: core_normal_pdf > > ### ** Examples > > # Standard normal density at a few quantiles. > core_normal_pdf(c(-1, 0, 1)) [1] 0.2419707 0.3989423 0.2419707 > > # Peak of the standard normal is 1/sqrt(2*pi) at x = 0. > core_normal_pdf(0) [1] 0.3989423 > > # Shift and scale via `mean` and `sd`. > core_normal_pdf(5, mean = 5, sd = 2) # peak of N(5, 2) [1] 0.1994711 > core_normal_pdf(c(0, 5, 10), mean = 5, sd = 2) [1] 0.00876415 0.19947114 0.00876415 > > # Identical to stats::dnorm(). > all.equal(core_normal_pdf(-2:2, 0, 1), stats::dnorm(-2:2, 0, 1)) [1] TRUE > > > > cleanEx() > nameEx("core_sha256") > ### * core_sha256 > > flush(stderr()); flush(stdout()) > > ### Name: core_sha256 > ### Title: SHA-256 hex digest (C backend) > ### Aliases: core_sha256 > > ### ** Examples > > # Hash a character scalar (NIST test vector for "abc"). > core_sha256("abc") [1] "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" > # ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad > > # Vectorised over character input: one digest per element. > core_sha256(c("abc", "def")) [1] "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" [2] "cb8379ac2098aa165029e3938a51da0bcecfc008fd6795f401178647f96c5b34" > > # Raw input hashes the bytes directly; identical to the character form. > identical(core_sha256("abc"), core_sha256(charToRaw("abc"))) [1] TRUE > > # Fingerprint an arbitrary object via its serialization. > core_sha256(serialize(list(a = 1L, b = "x"), NULL)) [1] "d8e966b9a409614aef2ce3a849533bc8a10c3d67c7bcf58c43929b93a4113378" > > > > cleanEx() > nameEx("core_sha512") > ### * core_sha512 > > flush(stderr()); flush(stdout()) > > ### Name: core_sha512 > ### Title: SHA-512 hex digest (C backend) > ### Aliases: core_sha512 > > ### ** Examples > > # FIPS 180-4 test vector for "abc". > core_sha512("abc") [1] "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" > > # Vectorised over character input. > core_sha512(c("abc", "def")) [1] "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" [2] "40a855bf0a93c1019d75dd5b59cd8157608811dd75c5977e07f3bc4be0cad98b22dde4db9ddb429fc2ad3cf9ca379fedf6c1dc4d4bb8829f10c2f0ee04a66663" > > # Raw input hashes the bytes directly, and agrees with the character > # form for the same bytes. > identical(core_sha512("abc"), core_sha512(charToRaw("abc"))) [1] TRUE > > # Twice the digest width of SHA-256. > c(sha256 = nchar(core_sha256("abc")), sha512 = nchar(core_sha512("abc"))) sha256 sha512 64 128 > > > > cleanEx() > nameEx("core_weighted") > ### * core_weighted > > flush(stderr()); flush(stdout()) > > ### Name: core_weighted > ### Title: Weighted mean and variance (C backend) > ### Aliases: core_weighted > > ### ** Examples > > x <- c(10, 20, 30, 40) > w <- c(1, 1, 2, 4) > core_weighted(x, w) mean variance 31.2500 169.0476 > > # The mean agrees with base R. > all.equal(core_weighted(x, w)[["mean"]], stats::weighted.mean(x, w)) [1] TRUE > > # Equal weights recover the unweighted variance. > all.equal(core_weighted(x, rep(1, 4))[["variance"]], stats::var(x)) [1] TRUE > > # A single dominant weight pulls the mean onto that observation. > core_weighted(x, c(1, 1, 1, 1000))[["mean"]] [1] 39.94018 > > > > cleanEx() > nameEx("correlation_table") > ### * correlation_table > > flush(stderr()); flush(stdout()) > > ### Name: correlation_table > ### Title: Full pairwise correlation table > ### Aliases: correlation_table > > ### ** Examples > > set.seed(1) > df <- data.frame(a = stats::rnorm(100), b = stats::rnorm(100)) > df$c <- df$a + stats::rnorm(100, sd = 0.2) > > correlation_table(df) ── Correlations (spearman) ─────────────────────────────────────── x y correlation n_pairs a b 0.039 100 a c 0.967 100 b c 0.015 100 ────────────────────────────────────────────────────────────────── > > # n_pairs shows how much data each figure rests on. > gappy <- df > gappy$a[1:80] <- NA > correlation_table(gappy) ── Correlations (spearman) ─────────────────────────────────────── x y correlation n_pairs a b 0.165 20 a c 0.959 20 b c 0.015 100 ────────────────────────────────────────────────────────────────── > > # A pair with too little overlap is NA, not a number from nothing. > thin <- df > thin$a[1:99] <- NA > correlation_table(thin)$correlation [1] NA NA 0.01508551 > > > > cleanEx() > nameEx("count_trend") > ### * count_trend > > flush(stderr()); flush(stdout()) > > ### Name: count_trend > ### Title: Trend in a count series, as a rate ratio per period > ### Aliases: count_trend > > ### ** Examples > > # A count falling by about 15% a year. > set.seed(3) > y <- stats::rpois(8, lambda = 200 * 0.85^(0:7)) > fit <- count_trend(y) > round(fit$rate_ratio, 3) [1] 0.869 > > # With a varying denominator the trend is in the rate. > count_trend(c(20, 25, 30), offset = c(1000, 1500, 2500))$rate_ratio [1] 0.7708656 > > > > cleanEx() > nameEx("cramers_v") > ### * cramers_v > > flush(stderr()); flush(stdout()) > > ### Name: cramers_v > ### Title: Association in a contingency table > ### Aliases: cramers_v > > ### ** Examples > > tbl <- rbind(c(120, 80), c(40, 160)) > cramers_v(tbl) $v [1] 0.4056758 $chisq [1] 66.66667 $df [1] 1 $p_value [1] 3.215263e-16 $n [1] 400 $min_expected [1] 80 $cells_below [1] 0 $method [1] "chi-square approximation" > > # No association gives a V near zero. > cramers_v(rbind(c(100, 100), c(100, 100)))$v [1] 0 > > # A sparse table's uncorrected V overstates the association. > sparse <- rbind(c(3, 1), c(1, 3)) > c(raw = cramers_v(sparse, bias_correct = FALSE)$v, + corrected = cramers_v(sparse)$v) raw corrected 0.5000000 0.3535534 > > > > cleanEx() > nameEx("derive_key") > ### * derive_key > > flush(stderr()); flush(stdout()) > > ### Name: derive_key > ### Title: Derive a key from a passphrase > ### Aliases: derive_key > > ### ** Examples > > # The published PBKDF2-HMAC-SHA256 vector: "password", "salt", 1 round. > derive_key("password", "salt", iterations = 1) [1] "120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b" > > # Deterministic, so verification can repeat it. > identical(derive_key("pw", "s", 1000), derive_key("pw", "s", 1000)) [1] TRUE > > # The salt, the passphrase and the iteration count all change the key. > derive_key("pw", "salt-a", 1000) == derive_key("pw", "salt-b", 1000) [1] FALSE > derive_key("pw", "s", 1000) == derive_key("pw", "s", 2000) [1] FALSE > > # Use it to sign a manifest from a passphrase rather than raw bytes. > salt <- paste(format(random_bytes(16)), collapse = "") > key <- derive_key("correct horse battery staple", salt) > sig <- capsule_sign("manifest-digest", key, scheme = "hmac") > capsule_verify("manifest-digest", sig, key) [1] TRUE > > # A longer key is a prefix-consistent extension of a shorter one. > identical(substring(derive_key("pw", "s", 10, length = 64), 1, 64), + derive_key("pw", "s", 10, length = 32)) [1] TRUE > > > > cleanEx() > nameEx("digest_object") > ### * digest_object > > flush(stderr()); flush(stdout()) > > ### Name: digest_object > ### Title: Digest an arbitrary R object > ### Aliases: digest_object > > ### ** Examples > > digest_object(list(a = 1L, b = "x")) [1] "49cceaf96020b3b5c40d2ffbac114a1d7a93474aa083516da4df3f82e7afd1c4" > > # Stable across calls, and sensitive to any change. > identical(digest_object(1:10), digest_object(1:10)) [1] TRUE > digest_object(1:10) == digest_object(1:11) [1] FALSE > > # Attributes are part of the object, so they are part of the digest. > digest_object(matrix(1:6, nrow = 2)) == digest_object(1:6) [1] FALSE > > # Any of the hashes, and a keyed fingerprint. > digest_object(mtcars, algo = "sha512") [1] "3bea6c8e5b622c3677149de5c31be5e4d0592767a8e97d14f16690ea72aa5ba0d7354e18d1bce2bc3ba836b392871f67e4fc97076ce6745c3a9e5a5fbf884a96" > digest_object(mtcars, algo = "crc32") [1] 1371658137 > digest_object(mtcars, algo = "blake2b", key = "secret") [1] "0137c7e84d6663d0032c112b7973b672b79123f65246b3c93ed31a80239454b3" > > # A data frame's digest pins the data, so it can go in a manifest. > digest_object(data.frame(x = 1:3)) [1] "74275c3f5e3bcc768b6156bf46ddb2ce0f026d383547a486b3b57dbc23417a32" > > > > cleanEx() > nameEx("download_data") > ### * download_data > > flush(stderr()); flush(stdout()) > > ### Name: download_data > ### Title: Download a File > ### Aliases: download_data > > ### ** Examples > > > > > cleanEx() > nameEx("drift_chisq") > ### * drift_chisq > > flush(stderr()); flush(stdout()) > > ### Name: drift_chisq > ### Title: Chi-square test for a categorical column > ### Aliases: drift_chisq > > ### ** Examples > > ref <- c(a = 50, b = 30, c = 20) > > # Counts matching the reference proportions: nothing to report. > drift_chisq(c(a = 100, b = 60, c = 40), ref) statistic df p_value 0 2 1 > > # A reallocated mix is detected. > drift_chisq(c(a = 40, b = 60, c = 100), ref) statistic df p_value 126 2 0 > > # Agrees with stats::chisq.test(). > o <- c(a = 40, b = 60, c = 100) > all.equal(drift_chisq(o, ref)[["statistic"]], + as.numeric(stats::chisq.test(o, p = ref / sum(ref))$statistic)) [1] TRUE > > # Raw vectors are tabulated for you. > drift_chisq(c("a", "a", "b", "b"), c("a", "b")) statistic df p_value 0 1 1 > > # A category the reference rules out, but which occurs, is a flat > # contradiction rather than a large finite statistic. > drift_chisq(c("a", "a", "b", "d"), c("a", "a", "b", "b")) statistic df p_value Inf 1 0 > > # When a new category is legitimate, compare two samples instead. > drift_homogeneity(c("a", "a", "b", "b"), c("a", "a", "b", "d")) statistic df p_value 1.3333333 2.0000000 0.5134171 > > > > cleanEx() > nameEx("drift_homogeneity") > ### * drift_homogeneity > > flush(stderr()); flush(stdout()) > > ### Name: drift_homogeneity > ### Title: Chi-square test of homogeneity for two categorical samples > ### Aliases: drift_homogeneity > > ### ** Examples > > set.seed(1) > a <- sample(c("x", "y", "z"), 300, TRUE) > b <- sample(c("x", "y", "z"), 300, TRUE) > > # Two draws from the same distribution: no evidence of a difference. > drift_homogeneity(a, b) statistic df p_value 0.5150386 2.0000000 0.7729667 > > # A reallocated mix is detected. > drift_homogeneity(a, sample(c("x", "y", "z"), 300, TRUE, + prob = c(0.7, 0.2, 0.1))) statistic df p_value 6.978222e+01 2.000000e+00 6.661338e-16 > > # Agrees with stats::chisq.test() on the 2-by-k table. > tab <- rbind(table(a), table(b)) > all.equal(drift_homogeneity(a, b)[["statistic"]], + as.numeric(stats::chisq.test(tab)$statistic)) [1] TRUE > > # It is more conservative than treating the reference as known, which > # is exactly the point. > drift_homogeneity(a, b)[["p_value"]] >= drift_chisq(b, a)[["p_value"]] [1] TRUE > > > > cleanEx() > nameEx("drift_ks") > ### * drift_ks > > flush(stderr()); flush(stdout()) > > ### Name: drift_ks > ### Title: Two-sample Kolmogorov-Smirnov test (C backend) > ### Aliases: drift_ks > > ### ** Examples > > set.seed(1) > ref <- stats::rnorm(200) > > # The same distribution: a small D and a large p-value. > drift_ks(ref, stats::rnorm(200)) statistic p_value n_eff 0.0600000 0.8642828 100.0000000 > > # A shifted distribution is detected. > drift_ks(ref, stats::rnorm(200, mean = 0.8)) statistic p_value n_eff 3.250000e-01 1.338317e-09 1.000000e+02 > > # So is a change in spread alone, which a mean comparison would miss. > drift_ks(ref, stats::rnorm(200, sd = 2.5)) statistic p_value n_eff 3.150000e-01 4.813445e-09 1.000000e+02 > > # The statistic agrees with stats::ks.test(). > a <- stats::rnorm(60); b <- stats::rnorm(45, 0.6) > all.equal(drift_ks(a, b)[["statistic"]], + as.numeric(suppressWarnings(stats::ks.test(a, b))$statistic)) [1] TRUE > > # Identical samples have nothing to report. > drift_ks(ref, ref)[["statistic"]] [1] 0 > > > > cleanEx() > nameEx("drift_psi") > ### * drift_psi > > flush(stderr()); flush(stdout()) > > ### Name: drift_psi > ### Title: Population stability index and Jensen-Shannon divergence (C > ### backend) > ### Aliases: drift_psi > > ### ** Examples > > set.seed(2) > ref <- stats::rnorm(500) > > # Same distribution: both indices near zero. > drift_psi(ref, stats::rnorm(500)) psi js_divergence 0.022072326 0.002752915 > > # A shift both indices register. > drift_psi(ref, stats::rnorm(500, mean = 1)) psi js_divergence 0.9543324 0.1053174 > > # A sample compared with itself has moved nowhere at all. > drift_psi(ref, ref) psi js_divergence 0 0 > > # The Jensen-Shannon divergence is bounded by log(2), whatever the > # shift, which is what makes it comparable across columns. > drift_psi(c(1, 1, 1), c(9, 9, 9))[["js_divergence"]] <= log(2) [1] TRUE > > > > cleanEx() > nameEx("duplicate_rows") > ### * duplicate_rows > > flush(stderr()); flush(stdout()) > > ### Name: duplicate_rows > ### Title: Duplicated rows, with their groups > ### Aliases: duplicate_rows > > ### ** Examples > > df <- data.frame(id = c(1, 2, 2, 3, 3, 3), + value = c("a", "b", "b", "c", "d", "c"), + stringsAsFactors = FALSE) > > # Duplicated on every column. > duplicate_rows(df) id value dupe_count 1 2 b 2 2 2 b 2 3 3 c 2 4 3 c 2 > > # Duplicated on the identifier alone, which catches more. > duplicate_rows(df, "id") id value dupe_count 1 2 b 2 2 2 b 2 3 3 c 3 4 3 d 3 5 3 c 3 > > # No duplicates gives zero rows, not an error. > duplicate_rows(data.frame(x = 1:3)) [1] x dupe_count <0 rows> (or 0-length row.names) > > > > cleanEx() > nameEx("eb_rates") > ### * eb_rates > > flush(stderr()); flush(stdout()) > > ### Name: eb_rates > ### Title: Empirical Bayes rates, shrunk toward the overall experience > ### Aliases: eb_rates > > ### ** Examples > > # Three areas, one of them tiny. The tiny area's raw ratio is > # extreme; its shrunk one is not. > eb_rates(observed = c(30, 45, 2), expected = c(25, 50, 0.5), + area = c("North", "South", "Tiny")) area observed expected sir eb shrinkage nu alpha 1 North 30 25.0 1.2 1.1073869 0.5141392 26.98066 26.45506 2 South 45 50.0 0.9 0.9414767 0.3460211 26.98066 26.45506 3 Tiny 2 0.5 4.0 1.0751472 0.9814506 26.98066 26.45506 > > > > cleanEx() > nameEx("environment_diff") > ### * environment_diff > > flush(stderr()); flush(stdout()) > > ### Name: environment_diff > ### Title: Compare two captured environments > ### Aliases: environment_diff > > ### ** Examples > > a <- capture_environment() > b <- a > > # An environment matches itself. > environment_diff(a, b)$identical [1] TRUE > > # Stage a moved dependency and a removed one. > if (length(b$packages)) { + nm <- names(b$packages)[1] + b$packages[[nm]] <- "0.0.0" + environment_diff(a, b)$packages + } package a b change 1 base 4.7.0 0.0.0 changed > > # Whole manifests are accepted, not just the environment block. > m <- make_manifest(list(run = "demo")) > environment_diff(m, m)$identical [1] TRUE > > > > cleanEx() > nameEx("evalue_rr") > ### * evalue_rr > > flush(stderr()); flush(stdout()) > > ### Name: evalue_rr > ### Title: How strong would an unmeasured confounder have to be > ### Aliases: evalue_rr > > ### ** Examples > > # a risk ratio of 2 needs a confounder associated by 3.41 with both > evalue_rr(2) evalue_point 3.414214 > > # a protective effect is inverted, so 0.5 gives the same answer > evalue_rr(0.5) evalue_point 3.414214 > > # an interval that already includes the null needs nothing > evalue_rr(2, lo = 0.9, hi = 4.4) evalue_point evalue_limit 3.414214 1.000000 > > # and a strong result with a limit well above the null is harder to > # explain away > evalue_rr(3, lo = 2.1, hi = 4.3) evalue_point evalue_limit 5.449490 3.619868 > > > > cleanEx() > nameEx("expand_bands") > ### * expand_bands > > flush(stderr()); flush(stdout()) > > ### Name: expand_bands > ### Title: Expand a banded frequency table into per-unit values > ### Aliases: expand_bands > > ### ** Examples > > x <- expand_bands(c("1", "2 to 5", "Greater than 5"), + counts = c(10, 4, 2), open_upper_cap = 12) > table(x) x 1 3.5 9 10 4 2 > > gini(x) [1] 0.452381 > > > > cleanEx() > nameEx("expected_counts") > ### * expected_counts > > flush(stderr()); flush(stdout()) > > ### Name: expected_counts > ### Title: Expected counts under indirect standardisation > ### Aliases: expected_counts > > ### ** Examples > > d <- data.frame( + region = rep(c("North", "South", "East"), each = 2), + age = rep(c("18 to 24", "25 to 49"), 3), + n = c(30, 45, 12, 60, 8, 20), + pop = c(1000, 6000, 900, 9000, 400, 3500) + ) > > # Adjusting for size only. > expected_counts(d$n, d$pop, d$region) area observed population expected 1 East 28 3900 32.81250 2 North 75 7000 58.89423 3 South 72 9900 83.29327 > > # Adjusting for size AND age composition, which is the comparison > # that says something about the region. > expected_counts(d$n, d$pop, d$region, strata = d$age) area observed population expected 1 East 28 3900 32.34430 2 North 75 7000 62.27967 3 South 72 9900 80.37603 > > > > cleanEx() > nameEx("falsify_family") > ### * falsify_family > > flush(stderr()); flush(stdout()) > > ### Name: falsify_family > ### Title: Correct a family of falsification results for multiple testing > ### Aliases: falsify_family > > ### ** Examples > > # four statistics, one of which is real > set.seed(1) > d <- data.frame(x = rnorm(150)) > d$y <- 0.6 * d$x + rnorm(150) > d$a <- rnorm(150) > d$b <- rnorm(150) > fam <- list( + real = capsule_falsify(d, function(z) cor(z$x, z$y), + treatment = "x", n = 199, seed = 1), + noise_a = capsule_falsify(d, function(z) cor(z$a, z$y), + treatment = "a", n = 199, seed = 2), + noise_b = capsule_falsify(d, function(z) cor(z$b, z$y), + treatment = "b", n = 199, seed = 3)) > falsify_family(fam) ── Family of 3, corrected by holm at alpha 0.05 ────────────────── real p 0.005 adjusted 0.015 survives noise_a p 0.955 adjusted 1 noise_b p 0.995 adjusted 1 ────────────────────────────────────────────────────────────────── at the permutation floor (more permutations would be needed to say more): real ────────────────────────────────────────────────────────────────── > > # the correction is what stops the smallest of several from being > # read as the finding > falsify_family(c(a = 0.01, b = 0.04, c = 0.2, d = 0.5))$results name p adjusted survives 1 a 0.01 0.04 TRUE 2 b 0.04 0.12 FALSE 3 c 0.20 0.40 FALSE 4 d 0.50 0.50 FALSE > > > > cleanEx() > nameEx("fips_key") > ### * fips_key > > flush(stderr()); flush(stdout()) > > ### Name: fips_key > ### Title: Assemble a standardised key from raw key material > ### Aliases: fips_key > > ### ** Examples > > key <- fips_keygen("ML-DSA-44") > # the round trip through raw material changes nothing > again <- fips_key("ML-DSA-44", key$public, key$secret) > identical(again$secret, key$secret) [1] TRUE > > sig <- capsule_sign("m", again) > capsule_verify("m", sig, fips_key("ML-DSA-44", key$public)) [1] TRUE > > # material of the wrong length is refused > try(fips_key("ML-DSA-65", key$public, key$secret)) Error : `public` must be 1952 bytes of key material for ML-DSA-65 > > > > cleanEx() > nameEx("fips_keygen") > ### * fips_keygen > > flush(stderr()); flush(stdout()) > > ### Name: fips_keygen > ### Title: Generate a standardised post-quantum signing key > ### Aliases: fips_keygen fips_public_key > > ### ** Examples > > key <- fips_keygen("ML-DSA-65") > key$scheme [1] "ML-DSA-65" > > sig <- capsule_sign("a manifest digest", key) > capsule_verify("a manifest digest", sig, fips_public_key(key)) [1] TRUE > > # A context string binds the signature to its purpose: the same > # message signed for one context does not verify under another. > sig2 <- capsule_sign("a manifest digest", key, context = "release") > capsule_verify("a manifest digest", sig2, key, context = "release") [1] TRUE > capsule_verify("a manifest digest", sig2, key, context = "staging") [1] FALSE > > > > cleanEx() > nameEx("fips_mu") > ### * fips_mu > > flush(stderr()); flush(stdout()) > > ### Name: fips_mu > ### Title: Sign an ML-DSA message digest computed elsewhere > ### Aliases: fips_mu fips_sign_mu fips_verify_mu > > ### ** Examples > > key <- fips_keygen("ML-DSA-65") > mu <- fips_mu(key, "a manifest digest", context = "release") > length(mu) [1] 64 > > sig <- fips_sign_mu(key, mu) > fips_verify_mu(key, mu, sig) [1] TRUE > > # the same signature verifies the ordinary way, from the message > capsule_verify("a manifest digest", sig, key, context = "release") [1] TRUE > > # mu is computable from the PUBLIC key alone, which is what lets the > # message stay on the machine that has it > identical(fips_mu(fips_public_key(key), "a manifest digest", + context = "release"), mu) [1] TRUE > > > > cleanEx() > nameEx("fips_sizes") > ### * fips_sizes > > flush(stderr()); flush(stdout()) > > ### Name: fips_sizes > ### Title: Byte lengths of a standardised signature scheme > ### Aliases: fips_sizes > > ### ** Examples > > fips_sizes("ML-DSA-65") public_key secret_key signature seed opt_rand 1952 4032 3309 32 32 > fips_sizes("SLH-DSA-SHAKE-128s") public_key secret_key signature seed opt_rand 32 64 7856 48 16 > > # An SLH-DSA signature is far larger than an ML-DSA one at the same > # security level, which is the price of dropping the lattice > # assumption. > fips_sizes("SLH-DSA-SHAKE-128s")[["signature"]] > + fips_sizes("ML-DSA-44")[["signature"]] [1] TRUE > > > > cleanEx() > nameEx("fiscal_year_label") > ### * fiscal_year_label > > flush(stderr()); flush(stdout()) > > ### Name: fiscal_year_label > ### Title: Name a fiscal year by the years it spans > ### Aliases: fiscal_year_label > > ### ** Examples > > fiscal_year_label(2019:2023) [1] "2018/19" "2019/20" "2020/21" "2021/22" "2022/23" > > fiscal_year_label(2023, short = FALSE) [1] "2022/2023" > > fiscal_year_label(2023, sep = "-") [1] "2022-23" > > > > cleanEx() > nameEx("frequency_table") > ### * frequency_table > > flush(stderr()); flush(stdout()) > > ### Name: frequency_table > ### Title: Frequency table for one column > ### Aliases: frequency_table > > ### ** Examples > > df <- data.frame(grade = c("a", "b", "b", "c", NA, "b"), + stringsAsFactors = FALSE) > frequency_table(df, "grade") ── Frequency table ─────────────────────────────────────────────── value n pct pct_valid bar b 3 50.0 60.0 #################### a 1 16.7 20.0 ####### c 1 16.7 20.0 ####### – (missing) 1 16.7 – ####### ────────────────────────────────────────────────────────────────── > > # The two percentage columns differ exactly by the missingness. > frequency_table(df, "grade")[, c("pct", "pct_valid")] pct pct_valid 1 50.00000 60 2 16.66667 20 3 16.66667 20 4 16.66667 NA > > # A vector works directly. > frequency_table(c(1, 1, 2, 3, 3, 3)) ── Frequency table ─────────────────────────────────────────────── value n pct pct_valid bar 3 3 50.0 50.0 #################### 1 2 33.3 33.3 ############# 2 1 16.7 16.7 ####### ────────────────────────────────────────────────────────────────── > > # Natural order rather than frequency order. > frequency_table(c("c", "a", "b", "a"), sort = FALSE) ── Frequency table ─────────────────────────────────────────────── value n pct pct_valid bar a 2 50.0 50.0 #################### b 1 25.0 25.0 ########## c 1 25.0 25.0 ########## ────────────────────────────────────────────────────────────────── > > # Long tails are folded so the percentages still total 100. > set.seed(1) > ft <- frequency_table(sample(letters, 500, TRUE), max_levels = 5) > ft ── Frequency table ─────────────────────────────────────────────── value n pct pct_valid bar y 25 5.0 5.0 # e 24 4.8 4.8 # t 24 4.8 4.8 # a 23 4.6 4.6 # f 23 4.6 4.6 # (other) 381 76.2 76.2 #################### ────────────────────────────────────────────────────────────────── > sum(ft$pct) [1] 100 > > > > cleanEx() > nameEx("friendly_download") > ### * friendly_download > > flush(stderr()); flush(stdout()) > > ### Name: friendly_download > ### Title: Download a File With Diagnostic Error Messages > ### Aliases: friendly_download > > ### ** Examples > > > > > cleanEx() > nameEx("funnel_limits") > ### * funnel_limits > > flush(stderr()); flush(stdout()) > > ### Name: funnel_limits > ### Title: Funnel-plot control limits > ### Aliases: funnel_limits > > ### ** Examples > > # The funnel narrows as the expected count grows, which is the whole > # point: a ratio of 2 means nothing at an expected count of 2 and a > # great deal at an expected count of 200. > funnel_limits(c(2, 20, 200)) expected level lower upper 1 2 0.950 0.000 2.500 2 20 0.950 0.600 1.450 3 200 0.950 0.865 1.140 4 2 0.998 0.000 4.000 5 20 0.998 0.400 1.750 6 200 0.998 0.790 1.225 > > > > cleanEx() > nameEx("hill_tail_index") > ### * hill_tail_index > > flush(stderr()); flush(stdout()) > > ### Name: hill_tail_index > ### Title: Tail index of a heavy-tailed count > ### Aliases: hill_tail_index > > ### ** Examples > > # A continuous Pareto tail with exponent 2.5. > set.seed(1) > x <- (1 - stats::runif(5000))^(-1 / 1.5) > round(hill_tail_index(x, x_min = 1, discrete = FALSE)$alpha, 2) [1] 2.49 > > # A discrete power law, where the exact likelihood is needed: the > # closed-form correction is badly biased at a threshold of one. > k <- 1:10000 > p <- k^(-2.5) / sum(k^(-2.5)) > set.seed(2) > z <- sample(k, 5000, replace = TRUE, prob = p) > c(exact = round(hill_tail_index(z, x_min = 1)$alpha, 2), + approx = round(hill_tail_index(z, x_min = 1, approx = TRUE)$alpha, 2)) exact approx 2.46 2.00 > > # A short tail still returns an estimate, marked as not to be leaned > # on, and with a standard error that says the same thing. > short <- hill_tail_index(c(3, 4, 5, 9), x_min = 3) > c(alpha = round(short$alpha, 2), n = short$n_tail, + reliable = short$reliable) alpha n reliable 2.59 4.00 0.00 > > # Below `min_tail` there is nothing to estimate from. > hill_tail_index(c(3, 4), x_min = 3)$alpha [1] NA > > > > cleanEx() > nameEx("hurwitz_zeta") > ### * hurwitz_zeta > > flush(stderr()); flush(stdout()) > > ### Name: hurwitz_zeta > ### Title: Hurwitz zeta function > ### Aliases: hurwitz_zeta > > ### ** Examples > > # The Riemann zeta at even integers has a closed form. > c(hurwitz_zeta(2), pi^2 / 6) [1] 1.644934 1.644934 > c(hurwitz_zeta(4), pi^4 / 90) [1] 1.082323 1.082323 > > # Apery's constant. > hurwitz_zeta(3) [1] 1.202057 > > # Shifting the lower limit removes exactly the leading term. > hurwitz_zeta(2.5, 3) - hurwitz_zeta(2.5, 4) [1] 0.06415003 > 3^-2.5 [1] 0.06415003 > > # Outside the domain of convergence there is no value to return. > hurwitz_zeta(1) [1] NA > > > > cleanEx() > nameEx("infer_schema") > ### * infer_schema > > flush(stderr()); flush(stdout()) > > ### Name: infer_schema > ### Title: Infer a pinnable schema from a data frame > ### Aliases: infer_schema > > ### ** Examples > > set.seed(1) > df <- data.frame( + id = 1:100, + score = stats::runif(100, 0, 10), + grade = sample(c("a", "b", "c"), 100, TRUE), + note = paste0("free text ", 1:100), + stringsAsFactors = FALSE + ) > > sch <- infer_schema(df) > sch ── Inferred schema ─────────────────────────────────────────────── columns 4 rows 90 to 111 value sets 1 numeric ranges 2 id integer max NA 10.0% [ -8.9, 109.9] score numeric max NA 10.0% [-0.8446, 10.9] grade character max NA 10.0% a, b, c note character max NA 10.0% – free ────────────────────────────────────────────────────────────────── > > # The categorical column has its levels pinned; the free-text one does > # not, because it exceeds max_levels. > sch$expected_value_sets $grade [1] "a" "b" "c" > > # It validates the data it was learned from. > length(validate_schema(df, list(schema = sch))) [1] 0 > > # And catches a column that has gone missing, or a new category. > length(validate_schema(df[, -3], list(schema = sch))) > 0 [1] TRUE > bad <- df; bad$grade[1] <- "z" > length(validate_schema(bad, list(schema = sch))) > 0 [1] TRUE > > > > cleanEx() > nameEx("inline_hist") > ### * inline_hist > > flush(stderr()); flush(stdout()) > > ### Name: inline_hist > ### Title: Inline histogram for a numeric vector > ### Aliases: inline_hist > > ### ** Examples > > set.seed(1) > # A symmetric distribution peaks in the middle. > inline_hist(stats::rnorm(1000)) [1] "▁▂▄██▇▄▂▁▁" > > # A skewed one leans left. > inline_hist(stats::rexp(1000)) [1] "█▄▂▁▁▁▁▁▁▁" > > # Bimodality is visible here and in no single summary number. > inline_hist(c(stats::rnorm(500, -3), stats::rnorm(500, 3))) [1] "▁▅█▄▁▁▃█▆▁" > > # A constant column has no spread to show. > inline_hist(rep(5, 10)) [1] " █ " > > > > cleanEx() > nameEx("kem_decapsulate") > ### * kem_decapsulate > > flush(stderr()); flush(stdout()) > > ### Name: kem_decapsulate > ### Title: Recover a shared secret from an ML-KEM ciphertext > ### Aliases: kem_decapsulate > > ### ** Examples > > key <- kem_keygen(512) rmbl_mlkem_core.h:63:34: runtime error: signed integer overflow: 64778 * 62209 cannot be represented in type 'int' #0 0x7bcfe88ba0bc in rmbl_mlkem_core::montgomery_reduce(int) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:63 #1 0x7bcfe88ba0bc in rmbl_mlkem_core::ntt(short*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:136 #2 0x7bcfe88c6abb in rmbl_mlkem512::pke_keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:256 #3 0x7bcfe88c91ca in rmbl_mlkem512::keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:367 #4 0x7bcfe88d9a0c in C_rmbl_mlkem_keygen /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem.cpp:126 #5 0x00000075cd66 in R_doDotCall /data/localhost/ripley/R/svn/R-devel/src/main/dotcode.c:757 #6 0x000000900c47 in bcEval_loop /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:8704 #7 0x0000008d7ffb in bcEval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:7533 #8 0x00000087822a in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1167 #9 0x00000088ea3a in R_execClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2398 #10 0x00000089273d in applyClosure_core /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2314 #11 0x0000008788d8 in Rf_applyClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2333 #12 0x0000008788d8 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1278 #13 0x0000008a727e in do_set /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:3585 #14 0x000000878d06 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1230 #15 0x000000a211f8 in Rf_ReplIteration /data/localhost/ripley/R/svn/R-devel/src/main/main.c:264 #16 0x000000a211f8 in R_ReplConsole /data/localhost/ripley/R/svn/R-devel/src/main/main.c:319 #17 0x000000a3eeba in run_Rmainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1239 #18 0x000000a3ef52 in Rf_mainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1246 #19 0x0000004120af in main /data/localhost/ripley/R/svn/R-devel/src/main/Rmain.c:29 #20 0x7fcff4a0a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #21 0x7fcff4a0a797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #22 0x000000412a74 in _start (/data/localhost/ripley/R/gcc-SAN3/bin/exec/R+0x412a74) (BuildId: 9dff11dcd6e3f76486b274cbe4864e0a7249b59b) rmbl_mlkem_core.h:63:34: runtime error: signed integer overflow: 40196 * 62209 cannot be represented in type 'int' #0 0x7bcfe88b698e in rmbl_mlkem_core::montgomery_reduce(int) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:63 #1 0x7bcfe88b698e in rmbl_mlkem_core::basemul(short*, short const*, short const*, short) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:170 #2 0x7bcfe88c6f59 in rmbl_mlkem_core::poly_basemul(short*, short const*, short const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:183 #3 0x7bcfe88c6f59 in rmbl_mlkem512::vec_dot(short*, rmbl_mlkem512::PolyVec const*, rmbl_mlkem512::PolyVec const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:184 #4 0x7bcfe88c6f59 in rmbl_mlkem512::pke_keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:260 #5 0x7bcfe88c91ca in rmbl_mlkem512::keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:367 #6 0x7bcfe88d9a0c in C_rmbl_mlkem_keygen /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem.cpp:126 #7 0x00000075cd66 in R_doDotCall /data/localhost/ripley/R/svn/R-devel/src/main/dotcode.c:757 #8 0x000000900c47 in bcEval_loop /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:8704 #9 0x0000008d7ffb in bcEval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:7533 #10 0x00000087822a in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1167 #11 0x00000088ea3a in R_execClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2398 #12 0x00000089273d in applyClosure_core /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2314 #13 0x0000008788d8 in Rf_applyClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2333 #14 0x0000008788d8 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1278 #15 0x0000008a727e in do_set /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:3585 #16 0x000000878d06 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1230 #17 0x000000a211f8 in Rf_ReplIteration /data/localhost/ripley/R/svn/R-devel/src/main/main.c:264 #18 0x000000a211f8 in R_ReplConsole /data/localhost/ripley/R/svn/R-devel/src/main/main.c:319 #19 0x000000a3eeba in run_Rmainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1239 #20 0x000000a3ef52 in Rf_mainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1246 #21 0x0000004120af in main /data/localhost/ripley/R/svn/R-devel/src/main/Rmain.c:29 #22 0x7fcff4a0a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #23 0x7fcff4a0a797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #24 0x000000412a74 in _start (/data/localhost/ripley/R/gcc-SAN3/bin/exec/R+0x412a74) (BuildId: 9dff11dcd6e3f76486b274cbe4864e0a7249b59b) rmbl_mlkem_core.h:63:34: runtime error: signed integer overflow: 55498 * 62209 cannot be represented in type 'int' #0 0x7bcfe88b6c30 in rmbl_mlkem_core::montgomery_reduce(int) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:63 #1 0x7bcfe88b6c30 in rmbl_mlkem_core::basemul(short*, short const*, short const*, short) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:173 #2 0x7bcfe88c6f59 in rmbl_mlkem_core::poly_basemul(short*, short const*, short const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:183 #3 0x7bcfe88c6f59 in rmbl_mlkem512::vec_dot(short*, rmbl_mlkem512::PolyVec const*, rmbl_mlkem512::PolyVec const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:184 #4 0x7bcfe88c6f59 in rmbl_mlkem512::pke_keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:260 #5 0x7bcfe88c91ca in rmbl_mlkem512::keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:367 #6 0x7bcfe88d9a0c in C_rmbl_mlkem_keygen /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem.cpp:126 #7 0x00000075cd66 in R_doDotCall /data/localhost/ripley/R/svn/R-devel/src/main/dotcode.c:757 #8 0x000000900c47 in bcEval_loop /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:8704 #9 0x0000008d7ffb in bcEval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:7533 #10 0x00000087822a in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1167 #11 0x00000088ea3a in R_execClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2398 #12 0x00000089273d in applyClosure_core /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2314 #13 0x0000008788d8 in Rf_applyClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2333 #14 0x0000008788d8 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1278 #15 0x0000008a727e in do_set /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:3585 #16 0x000000878d06 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1230 #17 0x000000a211f8 in Rf_ReplIteration /data/localhost/ripley/R/svn/R-devel/src/main/main.c:264 #18 0x000000a211f8 in R_ReplConsole /data/localhost/ripley/R/svn/R-devel/src/main/main.c:319 #19 0x000000a3eeba in run_Rmainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1239 #20 0x000000a3ef52 in Rf_mainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1246 #21 0x0000004120af in main /data/localhost/ripley/R/svn/R-devel/src/main/Rmain.c:29 #22 0x7fcff4a0a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #23 0x7fcff4a0a797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #24 0x000000412a74 in _start (/data/localhost/ripley/R/gcc-SAN3/bin/exec/R+0x412a74) (BuildId: 9dff11dcd6e3f76486b274cbe4864e0a7249b59b) rmbl_mlkem_core.h:63:34: runtime error: signed integer overflow: 62520 * 62209 cannot be represented in type 'int' #0 0x7bcfe88b6abb in rmbl_mlkem_core::montgomery_reduce(int) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:63 #1 0x7bcfe88b6abb in rmbl_mlkem_core::basemul(short*, short const*, short const*, short) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:174 #2 0x7bcfe88c6f59 in rmbl_mlkem_core::poly_basemul(short*, short const*, short const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:183 #3 0x7bcfe88c6f59 in rmbl_mlkem512::vec_dot(short*, rmbl_mlkem512::PolyVec const*, rmbl_mlkem512::PolyVec const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:184 #4 0x7bcfe88c6f59 in rmbl_mlkem512::pke_keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:260 #5 0x7bcfe88c91ca in rmbl_mlkem512::keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:367 #6 0x7bcfe88d9a0c in C_rmbl_mlkem_keygen /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem.cpp:126 #7 0x00000075cd66 in R_doDotCall /data/localhost/ripley/R/svn/R-devel/src/main/dotcode.c:757 #8 0x000000900c47 in bcEval_loop /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:8704 #9 0x0000008d7ffb in bcEval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:7533 #10 0x00000087822a in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1167 #11 0x00000088ea3a in R_execClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2398 #12 0x00000089273d in applyClosure_core /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2314 #13 0x0000008788d8 in Rf_applyClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2333 #14 0x0000008788d8 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1278 #15 0x0000008a727e in do_set /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:3585 #16 0x000000878d06 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1230 #17 0x000000a211f8 in Rf_ReplIteration /data/localhost/ripley/R/svn/R-devel/src/main/main.c:264 #18 0x000000a211f8 in R_ReplConsole /data/localhost/ripley/R/svn/R-devel/src/main/main.c:319 #19 0x000000a3eeba in run_Rmainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1239 #20 0x000000a3ef52 in Rf_mainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1246 #21 0x0000004120af in main /data/localhost/ripley/R/svn/R-devel/src/main/Rmain.c:29 #22 0x7fcff4a0a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #23 0x7fcff4a0a797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #24 0x000000412a74 in _start (/data/localhost/ripley/R/gcc-SAN3/bin/exec/R+0x412a74) (BuildId: 9dff11dcd6e3f76486b274cbe4864e0a7249b59b) rmbl_mlkem_core.h:63:34: runtime error: signed integer overflow: 48755 * 62209 cannot be represented in type 'int' #0 0x7bcfe88b6e26 in rmbl_mlkem_core::montgomery_reduce(int) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:63 #1 0x7bcfe88b6e26 in rmbl_mlkem_core::basemul(short*, short const*, short const*, short) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:176 #2 0x7bcfe88c6f59 in rmbl_mlkem_core::poly_basemul(short*, short const*, short const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:183 #3 0x7bcfe88c6f59 in rmbl_mlkem512::vec_dot(short*, rmbl_mlkem512::PolyVec const*, rmbl_mlkem512::PolyVec const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:184 #4 0x7bcfe88c6f59 in rmbl_mlkem512::pke_keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:260 #5 0x7bcfe88c91ca in rmbl_mlkem512::keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:367 #6 0x7bcfe88d9a0c in C_rmbl_mlkem_keygen /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem.cpp:126 #7 0x00000075cd66 in R_doDotCall /data/localhost/ripley/R/svn/R-devel/src/main/dotcode.c:757 #8 0x000000900c47 in bcEval_loop /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:8704 #9 0x0000008d7ffb in bcEval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:7533 #10 0x00000087822a in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1167 #11 0x00000088ea3a in R_execClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2398 #12 0x00000089273d in applyClosure_core /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2314 #13 0x0000008788d8 in Rf_applyClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2333 #14 0x0000008788d8 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1278 #15 0x0000008a727e in do_set /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:3585 #16 0x000000878d06 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1230 #17 0x000000a211f8 in Rf_ReplIteration /data/localhost/ripley/R/svn/R-devel/src/main/main.c:264 #18 0x000000a211f8 in R_ReplConsole /data/localhost/ripley/R/svn/R-devel/src/main/main.c:319 #19 0x000000a3eeba in run_Rmainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1239 #20 0x000000a3ef52 in Rf_mainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1246 #21 0x0000004120af in main /data/localhost/ripley/R/svn/R-devel/src/main/Rmain.c:29 #22 0x7fcff4a0a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #23 0x7fcff4a0a797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #24 0x000000412a74 in _start (/data/localhost/ripley/R/gcc-SAN3/bin/exec/R+0x412a74) (BuildId: 9dff11dcd6e3f76486b274cbe4864e0a7249b59b) rmbl_mlkem_core.h:63:34: runtime error: signed integer overflow: 55196 * 62209 cannot be represented in type 'int' #0 0x7bcfe88b6dd0 in rmbl_mlkem_core::montgomery_reduce(int) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:63 #1 0x7bcfe88b6dd0 in rmbl_mlkem_core::basemul(short*, short const*, short const*, short) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:171 #2 0x7bcfe88c6f59 in rmbl_mlkem_core::poly_basemul(short*, short const*, short const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:183 #3 0x7bcfe88c6f59 in rmbl_mlkem512::vec_dot(short*, rmbl_mlkem512::PolyVec const*, rmbl_mlkem512::PolyVec const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:184 #4 0x7bcfe88c6f59 in rmbl_mlkem512::pke_keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:260 #5 0x7bcfe88c91ca in rmbl_mlkem512::keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:367 #6 0x7bcfe88d9a0c in C_rmbl_mlkem_keygen /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem.cpp:126 #7 0x00000075cd66 in R_doDotCall /data/localhost/ripley/R/svn/R-devel/src/main/dotcode.c:757 #8 0x000000900c47 in bcEval_loop /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:8704 #9 0x0000008d7ffb in bcEval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:7533 #10 0x00000087822a in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1167 #11 0x00000088ea3a in R_execClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2398 #12 0x00000089273d in applyClosure_core /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2314 #13 0x0000008788d8 in Rf_applyClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2333 #14 0x0000008788d8 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1278 #15 0x0000008a727e in do_set /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:3585 #16 0x000000878d06 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1230 #17 0x000000a211f8 in Rf_ReplIteration /data/localhost/ripley/R/svn/R-devel/src/main/main.c:264 #18 0x000000a211f8 in R_ReplConsole /data/localhost/ripley/R/svn/R-devel/src/main/main.c:319 #19 0x000000a3eeba in run_Rmainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1239 #20 0x000000a3ef52 in Rf_mainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1246 #21 0x0000004120af in main /data/localhost/ripley/R/svn/R-devel/src/main/Rmain.c:29 #22 0x7fcff4a0a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #23 0x7fcff4a0a797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #24 0x000000412a74 in _start (/data/localhost/ripley/R/gcc-SAN3/bin/exec/R+0x412a74) (BuildId: 9dff11dcd6e3f76486b274cbe4864e0a7249b59b) rmbl_mlkem_core.h:63:34: runtime error: signed integer overflow: 49808 * 62209 cannot be represented in type 'int' #0 0x7bcfe88c8588 in rmbl_mlkem_core::montgomery_reduce(int) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:63 #1 0x7bcfe88c8588 in rmbl_mlkem512::pke_keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:263 #2 0x7bcfe88c91ca in rmbl_mlkem512::keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:367 #3 0x7bcfe88d9a0c in C_rmbl_mlkem_keygen /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem.cpp:126 #4 0x00000075cd66 in R_doDotCall /data/localhost/ripley/R/svn/R-devel/src/main/dotcode.c:757 #5 0x000000900c47 in bcEval_loop /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:8704 #6 0x0000008d7ffb in bcEval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:7533 #7 0x00000087822a in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1167 #8 0x00000088ea3a in R_execClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2398 #9 0x00000089273d in applyClosure_core /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2314 #10 0x0000008788d8 in Rf_applyClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2333 #11 0x0000008788d8 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1278 #12 0x0000008a727e in do_set /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:3585 #13 0x000000878d06 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1230 #14 0x000000a211f8 in Rf_ReplIteration /data/localhost/ripley/R/svn/R-devel/src/main/main.c:264 #15 0x000000a211f8 in R_ReplConsole /data/localhost/ripley/R/svn/R-devel/src/main/main.c:319 #16 0x000000a3eeba in run_Rmainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1239 #17 0x000000a3ef52 in Rf_mainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1246 #18 0x0000004120af in main /data/localhost/ripley/R/svn/R-devel/src/main/Rmain.c:29 #19 0x7fcff4a0a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #20 0x7fcff4a0a797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #21 0x000000412a74 in _start (/data/localhost/ripley/R/gcc-SAN3/bin/exec/R+0x412a74) (BuildId: 9dff11dcd6e3f76486b274cbe4864e0a7249b59b) > sent <- kem_encapsulate(kem_public_key(key)) rmbl_mlkem_core.h:63:34: runtime error: signed integer overflow: 56564 * 62209 cannot be represented in type 'int' #0 0x7bcfe88ba5cb in rmbl_mlkem_core::montgomery_reduce(int) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:63 #1 0x7bcfe88ba5cb in rmbl_mlkem_core::invntt(short*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:157 #2 0x7bcfe88ca17a in rmbl_mlkem512::pke_encrypt(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:304 #3 0x7bcfe88cbc65 in rmbl_mlkem512::encaps(unsigned char*, unsigned char*, unsigned char const*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:383 #4 0x7bcfe88ded78 in C_rmbl_mlkem_encaps /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem.cpp:149 #5 0x00000075cd1a in R_doDotCall /data/localhost/ripley/R/svn/R-devel/src/main/dotcode.c:760 #6 0x000000900c47 in bcEval_loop /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:8704 #7 0x0000008d7ffb in bcEval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:7533 #8 0x00000087822a in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1167 #9 0x00000088ea3a in R_execClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2398 #10 0x00000089273d in applyClosure_core /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2314 #11 0x0000008788d8 in Rf_applyClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2333 #12 0x0000008788d8 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1278 #13 0x0000008a727e in do_set /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:3585 #14 0x000000878d06 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1230 #15 0x000000a211f8 in Rf_ReplIteration /data/localhost/ripley/R/svn/R-devel/src/main/main.c:264 #16 0x000000a211f8 in R_ReplConsole /data/localhost/ripley/R/svn/R-devel/src/main/main.c:319 #17 0x000000a3eeba in run_Rmainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1239 #18 0x000000a3ef52 in Rf_mainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1246 #19 0x0000004120af in main /data/localhost/ripley/R/svn/R-devel/src/main/Rmain.c:29 #20 0x7fcff4a0a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #21 0x7fcff4a0a797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #22 0x000000412a74 in _start (/data/localhost/ripley/R/gcc-SAN3/bin/exec/R+0x412a74) (BuildId: 9dff11dcd6e3f76486b274cbe4864e0a7249b59b) rmbl_mlkem_core.h:63:34: runtime error: signed integer overflow: 43904 * 62209 cannot be represented in type 'int' #0 0x7bcfe88baac5 in rmbl_mlkem_core::montgomery_reduce(int) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:63 #1 0x7bcfe88baac5 in rmbl_mlkem_core::invntt(short*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:163 #2 0x7bcfe88ca17a in rmbl_mlkem512::pke_encrypt(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:304 #3 0x7bcfe88cbc65 in rmbl_mlkem512::encaps(unsigned char*, unsigned char*, unsigned char const*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:383 #4 0x7bcfe88ded78 in C_rmbl_mlkem_encaps /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem.cpp:149 #5 0x00000075cd1a in R_doDotCall /data/localhost/ripley/R/svn/R-devel/src/main/dotcode.c:760 #6 0x000000900c47 in bcEval_loop /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:8704 #7 0x0000008d7ffb in bcEval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:7533 #8 0x00000087822a in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1167 #9 0x00000088ea3a in R_execClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2398 #10 0x00000089273d in applyClosure_core /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2314 #11 0x0000008788d8 in Rf_applyClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2333 #12 0x0000008788d8 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1278 #13 0x0000008a727e in do_set /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:3585 #14 0x000000878d06 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1230 #15 0x000000a211f8 in Rf_ReplIteration /data/localhost/ripley/R/svn/R-devel/src/main/main.c:264 #16 0x000000a211f8 in R_ReplConsole /data/localhost/ripley/R/svn/R-devel/src/main/main.c:319 #17 0x000000a3eeba in run_Rmainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1239 #18 0x000000a3ef52 in Rf_mainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1246 #19 0x0000004120af in main /data/localhost/ripley/R/svn/R-devel/src/main/Rmain.c:29 #20 0x7fcff4a0a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #21 0x7fcff4a0a797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #22 0x000000412a74 in _start (/data/localhost/ripley/R/gcc-SAN3/bin/exec/R+0x412a74) (BuildId: 9dff11dcd6e3f76486b274cbe4864e0a7249b59b) > identical(kem_decapsulate(key, sent$ciphertext), sent$shared) [1] TRUE > > # a tampered ciphertext returns a secret, and it is the wrong one > bad <- sent$ciphertext > substring(bad, 3L, 4L) <- "ff" > other <- kem_decapsulate(key, bad) > nchar(other) == 64L [1] TRUE > identical(other, sent$shared) [1] FALSE > > > > cleanEx() > nameEx("kem_encapsulate") > ### * kem_encapsulate > > flush(stderr()); flush(stdout()) > > ### Name: kem_encapsulate > ### Title: Encapsulate a shared secret under an ML-KEM key > ### Aliases: kem_encapsulate > > ### ** Examples > > key <- kem_keygen(512) > a <- kem_encapsulate(key) > nchar(a$ciphertext) / 2 == kem_sizes(512)[["ciphertext"]] [1] TRUE > > # two encapsulations to one key give different secrets > b <- kem_encapsulate(key) > identical(a$shared, b$shared) [1] FALSE > > # both decapsulate correctly > identical(kem_decapsulate(key, a$ciphertext), a$shared) [1] TRUE > identical(kem_decapsulate(key, b$ciphertext), b$shared) [1] TRUE > > > > cleanEx() > nameEx("kem_keygen") > ### * kem_keygen > > flush(stderr()); flush(stdout()) > > ### Name: kem_keygen > ### Title: Generate an ML-KEM key pair > ### Aliases: kem_keygen kem_public_key > > ### ** Examples > > key <- kem_keygen(768) rmbl_mlkem_core.h:63:34: runtime error: signed integer overflow: 41860 * 62209 cannot be represented in type 'int' #0 0x7bcfe88d01eb in rmbl_mlkem_core::montgomery_reduce(int) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_core.h:63 #1 0x7bcfe88d01eb in rmbl_mlkem768::pke_keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:263 #2 0x7bcfe88d0e5a in rmbl_mlkem768::keygen(unsigned char*, unsigned char*, unsigned char const*) /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem_body.h:367 #3 0x7bcfe88d9c3f in C_rmbl_mlkem_keygen /data/localhost/ripley/R/packages/tests-gcc-SAN/rmoriebricklayer/src/rmbl_mlkem.cpp:126 #4 0x00000075cd66 in R_doDotCall /data/localhost/ripley/R/svn/R-devel/src/main/dotcode.c:757 #5 0x000000900c47 in bcEval_loop /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:8704 #6 0x0000008d7ffb in bcEval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:7533 #7 0x00000087822a in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1167 #8 0x00000088ea3a in R_execClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2398 #9 0x00000089273d in applyClosure_core /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2314 #10 0x0000008788d8 in Rf_applyClosure /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:2333 #11 0x0000008788d8 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1278 #12 0x0000008a727e in do_set /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:3585 #13 0x000000878d06 in Rf_eval /data/localhost/ripley/R/svn/R-devel/src/main/eval.c:1230 #14 0x000000a211f8 in Rf_ReplIteration /data/localhost/ripley/R/svn/R-devel/src/main/main.c:264 #15 0x000000a211f8 in R_ReplConsole /data/localhost/ripley/R/svn/R-devel/src/main/main.c:319 #16 0x000000a3eeba in run_Rmainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1239 #17 0x000000a3ef52 in Rf_mainloop /data/localhost/ripley/R/svn/R-devel/src/main/main.c:1246 #18 0x0000004120af in main /data/localhost/ripley/R/svn/R-devel/src/main/Rmain.c:29 #19 0x7fcff4a0a680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #20 0x7fcff4a0a797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 5bd941be836f538fe5e10eff508f7f5dd94905a6) #21 0x000000412a74 in _start (/data/localhost/ripley/R/gcc-SAN3/bin/exec/R+0x412a74) (BuildId: 9dff11dcd6e3f76486b274cbe4864e0a7249b59b) > pub <- kem_public_key(key) > > # the sender holds only the public key > sent <- kem_encapsulate(pub) > # the recipient recovers the same secret from the ciphertext > got <- kem_decapsulate(key, sent$ciphertext) > identical(sent$shared, got) [1] TRUE > > # a corrupted ciphertext yields a DIFFERENT secret, not an error > bad <- sent$ciphertext > substring(bad, 1L, 2L) <- "00" > identical(kem_decapsulate(key, bad), got) [1] FALSE > > > > cleanEx() > nameEx("kem_sizes") > ### * kem_sizes > > flush(stderr()); flush(stdout()) > > ### Name: kem_sizes > ### Title: Byte lengths of an ML-KEM parameter set > ### Aliases: kem_sizes > > ### ** Examples > > kem_sizes(768) encapsulation_key decapsulation_key ciphertext seed 1184 2400 1088 64 shared_secret 32 > > # the shared secret is 32 bytes at every level: the level buys > # security margin, not a longer secret > vapply(c(512, 768, 1024), + function(l) kem_sizes(l)[["shared_secret"]], integer(1)) [1] 32 32 32 > > > > cleanEx() > nameEx("load_provenance") > ### * load_provenance > > flush(stderr()); flush(stdout()) > > ### Name: load_provenance > ### Title: Load a Pinned Data-Provenance Record > ### Aliases: load_provenance > > ### ** Examples > > prov_file <- tempfile(fileext = ".json") > writeLines('{"dataset": {"title": "demo"}, "sha256": "abc"}', prov_file) > prov <- load_provenance(prov_file) > prov$dataset$title [1] "demo" > load_provenance(file.path(tempdir(), "no-such-file.json")) # NULL NULL > > > > cleanEx() > nameEx("mahalanobis_outliers") > ### * mahalanobis_outliers > > flush(stderr()); flush(stdout()) > > ### Name: mahalanobis_outliers > ### Title: Multivariate outliers by Mahalanobis distance > ### Aliases: mahalanobis_outliers > > ### ** Examples > > set.seed(1) > n <- 200 > df <- data.frame(height = stats::rnorm(n, 170, 10)) > df$weight <- df$height * 0.5 + stats::rnorm(n, 0, 5) > > # A row that is ordinary on each variable but impossible jointly. > df[1, ] <- list(height = 150, weight = 140) > > out <- mahalanobis_outliers(df) > head(out, 3) ── Mahalanobis outliers (robust) ───────────────────────────────── ! 1 of 3 rows beyond alpha = 0.001 row distance p_value outlier 1 9.45 <2e-16 TRUE 61 2.76 0.0224 FALSE 14 2.70 0.0258 FALSE ────────────────────────────────────────────────────────────────── > > # It is flagged, even though neither value is a marginal outlier. > out$row[1] == 1 [1] TRUE > range(df$height) [1] 147.8530 194.0162 > range(df$weight) [1] 67.07546 140.00000 > > # The classical version can be fooled by the outliers it should find. > mahalanobis_outliers(df, robust = FALSE)$distance[1] < + mahalanobis_outliers(df, robust = TRUE)$distance[1] [1] FALSE > > # A duplicated column has no distance defined, and is refused. > dup <- df > dup$height2 <- dup$height > try(mahalanobis_outliers(dup)) Error : the columns are collinear, so no Mahalanobis distance is defined. Drop the redundant column(s) -- drop_constant() and top_correlations() will find them. > > > > cleanEx() > nameEx("make_manifest") > ### * make_manifest > > flush(stderr()); flush(stdout()) > > ### Name: make_manifest > ### Title: Construct a Reproducibility Manifest > ### Aliases: make_manifest > > ### ** Examples > > # Minimal manifest, no environment capture. > man <- make_manifest(list(project = "demo-study", author = "A. Author"), + environment = FALSE) > names(man) # "meta" "results" [1] "meta" "results" > man$meta$project [1] "demo-study" > > # With environment = TRUE it also records R version / platform / packages. > full <- make_manifest(list(project = "demo"), environment = TRUE) > names(full) # adds "environment" [1] "meta" "results" "environment" > full$environment$r_version [1] "4.7.0" > > > > cleanEx() > nameEx("make_synthetic_column") > ### * make_synthetic_column > > flush(stderr()); flush(stdout()) > > ### Name: make_synthetic_column > ### Title: Generate One Synthetic Column From a Spec > ### Aliases: make_synthetic_column > > ### ** Examples > > set.seed(1) > # "sample": categorical draw, optionally weighted. > make_synthetic_column(list(type = "sample", values = list("a", "b"), + weights = list(0.7, 0.3)), 5) [1] "a" "a" "a" "b" "a" > > # "bernoulli": two-label draw at probability p. > make_synthetic_column(list(type = "bernoulli", p = 0.5, + labels = list("Yes", "No")), 5) [1] "No" "No" "No" "No" "Yes" > > # "poisson": counts with a floor via `min`. > make_synthetic_column(list(type = "poisson", lambda = 3, min = 1), 5) [1] 2 1 4 2 4 > > # "id_pattern": templated IDs (the {seq:05d} token is zero-padded). > make_synthetic_column(list(type = "id_pattern", + pattern = "case-{seq:05d}"), 3) [1] "case-00001" "case-00002" "case-00003" > > # "sequence": a running integer sequence from `from`. > make_synthetic_column(list(type = "sequence", from = 100), 4) [1] 100 101 102 103 > > # An unknown type errors. > try(make_synthetic_column(list(type = "nope"), 3)) Error in make_synthetic_column(list(type = "nope"), 3) : Unknown synthetic column type: nope > > > > cleanEx() > nameEx("make_synthetic_csv") > ### * make_synthetic_csv > > flush(stderr()); flush(stdout()) > > ### Name: make_synthetic_csv > ### Title: Generate a Synthetic CSV From a Schema Recipe > ### Aliases: make_synthetic_csv > > ### ** Examples > > recipe <- list( + n_rows = 20, seed = 42, + columns = list( + year = list(type = "sample", values = list(2024, 2025)), + alert = list(type = "bernoulli", p = 0.2), + visits = list(type = "poisson", lambda = 3, min = 1), + id = list(type = "id_pattern", pattern = "p-{seq:05d}") + ) + ) > out <- tempfile(fileext = ".csv") > res <- make_synthetic_csv(recipe, out) > res$rows # 20 [1] 20 > res$seed # 42 (reproducible) [1] 42 > > # The written CSV round-trips and has the declared columns. > df <- utils::read.csv(out) > dim(df) [1] 20 4 > names(df) [1] "year" "alert" "visits" "id" > > # `n_rows` overrides the recipe's own row count. > make_synthetic_csv(recipe, tempfile(fileext = ".csv"), n_rows = 5)$rows [1] 5 > > > > cleanEx() > nameEx("manifest_canonical") > ### * manifest_canonical > > flush(stderr()); flush(stdout()) > > ### Name: manifest_canonical > ### Title: The canonical serialisation of a manifest, and its digest > ### Aliases: manifest_canonical manifest_digest > > ### ** Examples > > a <- make_manifest(list(b = 2, a = 1), environment = FALSE) > b <- make_manifest(list(a = 1, b = 2), environment = FALSE) > # the same content in a different order has the same digest > identical(manifest_digest(a), manifest_digest(b)) [1] TRUE > > # full precision, so a recorded number can be checked later > m <- make_manifest(list(x = 1/3), environment = FALSE) > grepl("0.33333333333333331", manifest_canonical(m), fixed = TRUE) [1] TRUE > > > > cleanEx() > nameEx("manifest_recompute") > ### * manifest_recompute > > flush(stderr()); flush(stdout()) > > ### Name: manifest_recompute > ### Title: Recompute a manifest's recorded statistics against the data > ### Aliases: manifest_recompute > > ### ** Examples > > d <- data.frame(x = 1:10) > m <- make_manifest(list(dataset = "demo"), environment = FALSE) > m <- record(m, "mean_x", observed = mean(d$x), expected = 5.5) mean_x observed = 5.5000 expected = 5.5000 [PASS] > m <- record(m, "n", observed = nrow(d), expected = 10) n observed = 10.0000 expected = 10.0000 [PASS] > > # recomputing both reproduces them > res <- manifest_recompute(m, d, list(mean_x = function(z) mean(z$x), + n = function(z) nrow(z))) > res$ok [1] TRUE > res$results[, c("name", "recorded", "recomputed", "status")] name recorded recomputed status 1 mean_x 5.5 5.5 MATCH 2 n 10.0 10.0 MATCH > > # recomputing one leaves the other reported as unchecked > manifest_recompute(m, d, list(n = function(z) nrow(z)))$unchecked [1] "mean_x" > > # and data that no longer matches the record is caught > manifest_recompute(m, data.frame(x = 1:11), + list(n = function(z) nrow(z)))$ok [1] FALSE > > > > cleanEx() > nameEx("manifest_record_seed") > ### * manifest_record_seed > > flush(stderr()); flush(stdout()) > > ### Name: manifest_record_seed > ### Title: Record and restore the random number generator state > ### Aliases: manifest_record_seed manifest_restore_seed > > ### ** Examples > > set.seed(42) > m <- manifest_record_seed(make_manifest(list(a = 1), + environment = FALSE)) > first <- runif(3) > > # any amount of other work can happen in between > invisible(runif(1000)) > > manifest_restore_seed(m) > identical(runif(3), first) [1] TRUE > > > > cleanEx() > nameEx("mcar_test") > ### * mcar_test > > flush(stderr()); flush(stdout()) > > ### Name: mcar_test > ### Title: Little's test for data missing completely at random > ### Aliases: mcar_test > > ### ** Examples > > set.seed(1) > n <- 300 > x <- stats::rnorm(n) > y <- x + stats::rnorm(n) > > # Missing completely at random: a coin flip decides, so the test > # should not reject. > mcar <- data.frame(x = x, y = y) > mcar$y[sample(n, 90)] <- NA > mcar_test(mcar) ── Little's MCAR test ──────────────────────────────────────────── ✓ no departure from MCAR detected statistic 1.094 df 1 p-value 0.296 patterns 2 variables 2 rows used 300 EM iterations 13 Not evidence OF MCAR: a large p-value is a failure to detect a departure, and this test has little power on small samples. ────────────────────────────────────────────────────────────────── > > # Missing depending on the OTHER, observed variable: not MCAR, and > # detectable, because the pattern's mean of x is shifted. > mar <- data.frame(x = x, y = y) > mar$y[x > 0.4] <- NA > mcar_test(mar) ── Little's MCAR test ──────────────────────────────────────────── ✗ MCAR rejected: the missingness is related to the data statistic 180.118 df 1 p-value <2e-16 patterns 2 variables 2 rows used 300 EM iterations 69 ────────────────────────────────────────────────────────────────── > > # Complete data has one pattern and nothing to test. > mcar_test(data.frame(a = x, b = y))$df [1] 0 > > # A duplicated column makes the likelihood degenerate, and is refused. > dup <- mcar > dup$x2 <- dup$x > try(mcar_test(dup)) Error : the columns are collinear (or one is constant), so the multivariate normal likelihood Little's test is built on is degenerate. Drop the redundant column(s) first -- top_correlations() and drop_constant() will find them. > > # The EM estimates are the ML ones: with no missingness they are the > # column means and the ML (1/n) covariance. > fit <- mcar_test(data.frame(a = x, b = y)) > all.equal(fit$mu, c(mean(x), mean(y)), check.attributes = FALSE) [1] TRUE > > > > cleanEx() > nameEx("missing_runs") > ### * missing_runs > > flush(stderr()); flush(stdout()) > > ### Name: missing_runs > ### Title: Runs of consecutive missing values > ### Aliases: missing_runs > > ### ** Examples > > # One long outage and two isolated gaps, with the same total count. > df <- data.frame( + outage = c(1, 2, NA, NA, NA, NA, 7, 8), + scattered = c(1, NA, 3, 4, NA, 6, NA, NA) + ) > sum(is.na(df$outage)) == sum(is.na(df$scattered)) [1] TRUE > > missing_runs(df) ── Runs of consecutive missing values ──────────────────────────── column start end length outage 3 6 4 scattered 7 8 2 ────────────────────────────────────────────────────────────────── > > # Isolated gaps too, by lowering the threshold. > missing_runs(df, min_run = 1) ── Runs of consecutive missing values ──────────────────────────── column start end length outage 3 6 4 scattered 7 8 2 scattered 2 2 1 scattered 5 5 1 ────────────────────────────────────────────────────────────────── > > # A complete column has no runs. > missing_runs(data.frame(x = 1:5)) ── Runs of consecutive missing values ──────────────────────────── (none) ────────────────────────────────────────────────────────────────── > > > > cleanEx() > nameEx("missingness_map") > ### * missingness_map > > flush(stderr()); flush(stdout()) > > ### Name: missingness_map > ### Title: Text map of where the missing values are > ### Aliases: missingness_map > > ### ** Examples > > set.seed(1) > df <- data.frame( + complete = 1:100, + block = c(rep(NA, 30), 31:100), + scattered = ifelse(stats::runif(100) < 0.3, NA, 1), + mostly_gone = c(1:10, rep(NA, 90)) + ) > missingness_map(df) ── Missingness map ─────────────────────────────────────────────── cbsm olco moas pctt lktl eey tr_ eeg do n e 1 █▒ 6 █░ 11 █▒█ 16 █ █ 21 █▒█ 26 █░█ 31 ░█ 36 ░█ 41 █ 46 ░█ 51 ▒█ 56 ░█ 61 ░█ 66 ▒█ 71 █ 76 █ 81 █ 86 ▓█ 91 ▒█ 96 █ legend: ' ' none '█' all missing ────────────────────────────────────────────────────────────────── > > > > cleanEx() > nameEx("missingness_pattern") > ### * missingness_pattern > > flush(stderr()); flush(stdout()) > > ### Name: missingness_pattern > ### Title: Which columns are missing together > ### Aliases: missingness_pattern > > ### ** Examples > > # Two columns missing in the SAME rows: one structural gap. > structural <- data.frame( + id = 1:10, + a = c(rep(NA, 3), 4:10), + b = c(rep(NA, 3), 4:10) + ) > missingness_pattern(structural) ── Missingness patterns ────────────────────────────────────────── columns, in pattern order: id, a, b pattern n_rows pct_rows n_missing columns ... 7 70.0 0 .XX 3 30.0 2 a, b ────────────────────────────────────────────────────────────────── > > # The same per-column rates, but missing independently. > scattered <- data.frame( + id = 1:10, + a = c(rep(NA, 3), 4:10), + b = c(1:7, rep(NA, 3)) + ) > missingness_pattern(scattered) ── Missingness patterns ────────────────────────────────────────── columns, in pattern order: id, a, b pattern n_rows pct_rows n_missing columns ... 4 40.0 0 ..X 3 30.0 1 b .X. 3 30.0 1 a ────────────────────────────────────────────────────────────────── > > # A complete frame has exactly one pattern. > missingness_pattern(data.frame(x = 1:3, y = 4:6)) ── Missingness patterns ────────────────────────────────────────── columns, in pattern order: x, y pattern n_rows pct_rows n_missing columns .. 3 100.0 0 ────────────────────────────────────────────────────────────────── > > > > cleanEx() > nameEx("missingness_summary") > ### * missingness_summary > > flush(stderr()); flush(stdout()) > > ### Name: missingness_summary > ### Title: Missingness in one line per question > ### Aliases: missingness_summary > > ### ** Examples > > df <- data.frame(a = c(1, NA, 3), b = c(NA, NA, 3), c = 1:3) > missingness_summary(df) n_rows n_cols n_missing pct_missing 3.00000 3.00000 3.00000 33.33333 n_complete_rows pct_complete_rows n_cols_any_missing n_cols_all_missing 1.00000 33.33333 2.00000 0.00000 > > # A complete table is all zeros but for its dimensions. > missingness_summary(data.frame(x = 1:3, y = 4:6)) n_rows n_cols n_missing pct_missing 3 2 0 0 n_complete_rows pct_complete_rows n_cols_any_missing n_cols_all_missing 3 100 0 0 > > > > cleanEx() > nameEx("morans_i") > ### * morans_i > > flush(stderr()); flush(stdout()) > > ### Name: morans_i > ### Title: Global Moran's I over a neighbour list > ### Aliases: morans_i > > ### ** Examples > > # Six areas in a line, each adjacent to the next. > nb <- list(2L, c(1L, 3L), c(2L, 4L), c(3L, 5L), c(4L, 6L), 5L) > > # A smooth gradient is strongly positively autocorrelated. > set.seed(1) > morans_i(c(1, 2, 3, 4, 5, 6), nb, n_perm = 999L)[c("I", "p_value")] $I [1] 0.7142857 $p_value [1] 0.011 > > # An alternating pattern is negatively autocorrelated. > set.seed(1) > morans_i(c(1, 6, 1, 6, 1, 6), nb, n_perm = 999L)[c("I", "p_value")] $I [1] -1 $p_value [1] 0.199 > > # And the null expectation is not zero. > -1 / (6 - 1) [1] -0.2 > > > > cleanEx() > nameEx("oqs_keygen") > ### * oqs_keygen > > flush(stderr()); flush(stdout()) > > ### Name: oqs_keygen > ### Title: Generate a standardised post-quantum signing key (deprecated > ### name) > ### Aliases: oqs_keygen oqs_public_key > > ### ** Examples > > # Deprecated: use fips_keygen(). > key <- suppressWarnings(oqs_keygen("ML-DSA-65")) > key$scheme [1] "ML-DSA-65" > > > > cleanEx() > nameEx("parse_bands") > ### * parse_bands > > flush(stderr()); flush(stdout()) > > ### Name: parse_bands > ### Title: Parse banded category labels into numeric bounds > ### Aliases: parse_bands > > ### ** Examples > > parse_bands(c("1", "2 to 5", "6 to 10", "Greater than 10")) label lower upper open_lower open_upper 1 1 1 1 FALSE FALSE 2 2 to 5 2 5 FALSE FALSE 3 6 to 10 6 10 FALSE FALSE 4 Greater than 10 11 NA FALSE TRUE > > parse_bands(c("18 to 24", "25 to 49", "50+")) label lower upper open_lower open_upper 1 18 to 24 18 24 FALSE FALSE 2 25 to 49 25 49 FALSE FALSE 3 50+ 50 NA FALSE TRUE > > # An unrecognised label is reported as unparsed, not guessed at. > parse_bands(c("3", "unknown", "not stated")) label lower upper open_lower open_upper 1 3 3 3 FALSE FALSE 2 unknown NA NA FALSE FALSE 3 not stated NA NA FALSE FALSE > > > > cleanEx() > nameEx("period_days") > ### * period_days > > flush(stderr()); flush(stdout()) > > ### Name: period_days > ### Title: Period length in days, from dates > ### Aliases: period_days > > ### ** Examples > > period_days("2024-01-01", "2024-12-31") # a leap year [1] 366 > period_days("2023-01-01", "2023-12-31") [1] 365 > period_days("2025-04-01", "2026-03-31") # a fiscal year [1] 365 > > > > cleanEx() > nameEx("pqc_backends") > ### * pqc_backends > > flush(stderr()); flush(stdout()) > > ### Name: pqc_backends > ### Title: Available post-quantum signature schemes > ### Aliases: pqc_backends > > ### ** Examples > > pqc_backends() [1] "xmss-sha256" "ML-DSA-44" "ML-DSA-65" [4] "ML-DSA-87" "SLH-DSA-SHA2-128s" "SLH-DSA-SHA2-128f" [7] "SLH-DSA-SHA2-192s" "SLH-DSA-SHA2-192f" "SLH-DSA-SHA2-256s" [10] "SLH-DSA-SHA2-256f" "SLH-DSA-SHAKE-128s" "SLH-DSA-SHAKE-128f" [13] "SLH-DSA-SHAKE-192s" "SLH-DSA-SHAKE-192f" "SLH-DSA-SHAKE-256s" [16] "SLH-DSA-SHAKE-256f" > > # Every scheme is present in every build. > all(c("xmss-sha256", "ML-DSA-65", "SLH-DSA-SHAKE-128s") %in% + pqc_backends()) [1] TRUE > > > > cleanEx() > nameEx("pqc_keygen") > ### * pqc_keygen > > flush(stderr()); flush(stdout()) > > ### Name: pqc_keygen > ### Title: Generate a post-quantum signing key for capsule provenance > ### Aliases: pqc_keygen > > ### ** Examples > > # A small key, to keep the example quick. > key <- pqc_keygen(height = 3) > key$capacity # 8 signatures [1] 8 > key$next_index # none used yet [1] 0 > > # The public half is what a verifier needs; it carries no secret. > pub <- signing_public_key(key) > names(pub) [1] "root" "pub_seed" "height" "scheme" > > # Deterministic seeds reproduce the same key -- for tests only. > s1 <- paste(rep("11", 32), collapse = "") > s2 <- paste(rep("22", 32), collapse = "") > identical(pqc_keygen(3, s1, s2)$root, pqc_keygen(3, s1, s2)$root) [1] TRUE > > > > cleanEx() > nameEx("prereg_declare") > ### * prereg_declare > > flush(stderr()); flush(stdout()) > > ### Name: prereg_declare > ### Title: Declare an analysis before running it > ### Aliases: prereg_declare prereg_check > > ### ** Examples > > plan <- prereg_declare(c( + ate = "use of force is higher in the exposed division", + n_rows = "the extract has the row count the source publishes"), + note = "OTIS 2019-2024, division-level, pre-specified") > > # afterwards, against what was reported > prereg_check(plan, c("ate", "n_rows"))$ok [1] TRUE > > # dropping a declared outcome is outcome switching > prereg_check(plan, "n_rows")$declared_not_reported [1] "ate" > > # and adding undeclared ones is what makes a nominal p meaningless > prereg_check(plan, c("ate", "n_rows", "ate_by_year", + "ate_by_precinct"))$reported_not_declared [1] "ate_by_year" "ate_by_precinct" > > > > cleanEx() > nameEx("profile_columns") > ### * profile_columns > > flush(stderr()); flush(stdout()) > > ### Name: profile_columns > ### Title: Column report for a data frame > ### Aliases: profile_columns > > ### ** Examples > > set.seed(9) > df <- data.frame( + clean = stats::rnorm(100), + skewed = c(stats::rnorm(99), 500), + grade = sample(c("a", "b", "c"), 100, TRUE), + gappy = c(rep(NA, 10), stats::runif(90)) + ) > > profile_columns(df) ── Column profile ──────────────────────────────────────────────── column type n n_missing pct_missing n_distinct n_zero n_negative clean numeric 100 0 0 100 0 54 skewed numeric 100 0 0 100 0 48 grade character 100 0 0 3 – – gappy numeric 100 10 10 90 0 0 n_infinite mean sd median mad min max skewness n_outliers 0 -0.05351 0.9588 -0.1708 0.8777 -2.618 2.682 0.3145 3 0 4.874 50.02 0.04449 0.9517 -2.738 500 9.844 1 – – – – – – – – – 0 0.5019 0.2917 0.5243 0.3714 0.007639 0.9953 -0.04396 0 top q25 q50 q75 hist – -0.7457 -0.1708 0.422 ▁▁▃█▇█▃▃▂▁ – -0.7947 0.04449 0.6215 █ ▁ c – – – – – 0.2545 0.5243 0.7339 █▆▆█▆▇█▆█▆ ────────────────────────────────────────────────────────────────── > > # The mean and the median agree on `clean` and disagree sharply on > # `skewed`, which is the outlier announcing itself. > p <- profile_columns(df) > p[p$column %in% c("clean", "skewed"), c("column", "mean", "median")] column mean median 1 clean -0.05351488 -0.17078983 2 skewed 4.87405667 0.04448896 > > # The histogram column shows shape no summary number carries. > p[, c("column", "hist")] column hist 1 clean ▁▁▃█▇█▃▃▂▁ 2 skewed █ ▁ 3 grade