| Title: | Evidence Schema, Parsers, and Shared Primitives |
|---|---|
| Description: | Foundational package in the R4SUB (Ready for Submission) ecosystem. Defines the core evidence table schema, parsers, indicator abstractions, and scoring primitives needed to quantify clinical submission readiness. Provides a standardized contract for ingesting heterogeneous sources (validation outputs, metadata, traceability) into a single evidence framework. |
| Authors: | Pawan Rama Mali [aut, cre, cph] (ORCID: <https://orcid.org/0000-0001-7864-5819>) |
| Maintainer: | Pawan Rama Mali <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.3.0 |
| Built: | 2026-10-11 10:38:24 UTC |
| Source: | https://github.com/r4sub/r4subcore |
Returns the standard top-level and key subsections of the Analysis Data
Reviewer's Guide (ADRG), following the PHUSE ADRG completion guideline. This
is the checklist adrg_to_evidence() scores a guide against.
adrg_sections()adrg_sections()
A tibble with columns section_id, section_name, and required.
adrg_sections()adrg_sections()
Scores an Analysis Data Reviewer's Guide for completeness against the standard section catalog and emits R4SUB evidence rows, one per section.
adrg_to_evidence( present, ctx, source_name = "adrg", source_version = NULL, standard = adrg_sections() )adrg_to_evidence( present, ctx, source_name = "adrg", source_version = NULL, standard = adrg_sections() )
present |
A character vector of |
ctx |
|
source_name |
Source label. Default |
source_version |
Optional source version string. |
standard |
The section catalog to score against. Defaults to
|
ADRG and SDRG documents are Word or PDF, and reliable text extraction from
them is out of scope for this package. adrg_to_evidence() therefore takes a
structured summary of which sections a guide contains, which a document
pipeline (or a human reviewer) can produce, and turns it into evidence. A
present section passes. A missing required section fails at high severity; a
missing recommended section warns at low severity. The rows land in the
usability pillar, since the reviewer's guide is reviewer-facing documentation.
An evidence data.frame, one row per standard section.
ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(adrg_to_evidence(c("1", "2", "3", "4", "5"), ctx)) ev[, c("indicator_id", "severity", "result")]ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(adrg_to_evidence(c("1", "2", "3", "4", "5"), ctx)) ev[, c("indicator_id", "severity", "result")]
Computes summary scores from an evidence table, grouped by one or more columns.
aggregate_indicator_score( ev, by = "indicator_id", method = c("mean", "min", "weighted") )aggregate_indicator_score( ev, by = "indicator_id", method = c("mean", "min", "weighted") )
ev |
A valid evidence data.frame. |
by |
Character vector of column names to group by.
Default: |
method |
Aggregation method: |
A data.frame with grouping columns plus score (0–1) and
n_evidence (count of rows).
ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = rep("validation", 3), asset_id = rep("ADSL", 3), source_name = rep("pinnacle21", 3), indicator_id = c("SD0001", "SD0001", "SD0002"), indicator_name = c("SD0001", "SD0001", "SD0002"), indicator_domain = rep("quality", 3), severity = c("high", "medium", "low"), result = c("fail", "warn", "pass"), stringsAsFactors = FALSE ), ctx = ctx )) aggregate_indicator_score(ev, by = "indicator_id", method = "weighted")ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = rep("validation", 3), asset_id = rep("ADSL", 3), source_name = rep("pinnacle21", 3), indicator_id = c("SD0001", "SD0001", "SD0002"), indicator_name = c("SD0001", "SD0001", "SD0002"), indicator_domain = rep("quality", 3), severity = c("high", "medium", "low"), result = c("fail", "warn", "pass"), stringsAsFactors = FALSE ), ctx = ctx )) aggregate_indicator_score(ev, by = "indicator_id", method = "weighted")
Takes a data.frame and coerces it into a valid evidence table. Fills in
missing nullable columns with NA of the correct type and validates
controlled vocabulary columns.
as_evidence(x, ctx = NULL, ...)as_evidence(x, ctx = NULL, ...)
x |
A data.frame (or tibble) with at least the required evidence columns. |
ctx |
An optional r4sub_run_context. If provided, |
... |
Additional columns to set (e.g., |
A data.frame conforming to the evidence schema.
ctx <- r4sub_run_context("STUDY1", "DEV") df <- data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "P21-001", indicator_name = "Missing variable", indicator_domain = "quality", severity = "high", result = "fail", message = "Variable AGEU missing", stringsAsFactors = FALSE ) ev <- as_evidence(df, ctx = ctx)ctx <- r4sub_run_context("STUDY1", "DEV") df <- data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "P21-001", indicator_name = "Missing variable", indicator_domain = "quality", severity = "high", result = "fail", message = "Variable AGEU missing", stringsAsFactors = FALSE ) ev <- as_evidence(df, ctx = ctx)
Row-binds multiple evidence data.frames after validating each one.
bind_evidence(...)bind_evidence(...)
... |
Evidence data.frames to bind. |
A single combined evidence data.frame.
ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) make_ev <- function(ind_id) { suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = ind_id, indicator_name = ind_id, indicator_domain = "quality", severity = "low", result = "pass", stringsAsFactors = FALSE ), ctx = ctx )) } ev1 <- make_ev("IND-001") ev2 <- make_ev("IND-002") combined <- suppressMessages(bind_evidence(ev1, ev2)) nrow(combined)ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) make_ev <- function(ind_id) { suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = ind_id, indicator_name = ind_id, indicator_domain = "quality", severity = "low", result = "pass", stringsAsFactors = FALSE ), ctx = ctx )) } ev1 <- make_ev("IND-001") ev2 <- make_ev("IND-002") combined <- suppressMessages(bind_evidence(ev1, ev2)) nrow(combined)
Maps common result/status labels to the canonical set:
pass, fail, warn, na.
canon_result(x)canon_result(x)
x |
Character vector of result values. |
Character vector with canonical result labels.
canon_result(c("PASS", "Failed", "Warning", "N/A"))canon_result(c("PASS", "Failed", "Warning", "N/A"))
Maps common severity labels (case-insensitive) to the canonical set.
canon_severity(x)canon_severity(x)
x |
Character vector of severity values. |
Character vector with canonical severity labels.
canon_severity(c("HIGH", "Low", "warning", "Error"))canon_severity(c("HIGH", "Low", "warning", "Error"))
Compares the variables declared in Define-XML against the variables actually present in the datasets, and emits evidence for each: a match, a variable documented in Define but absent from the data, or a variable present in the data but not documented. Drift between Define-XML and the data is a common submission problem that reviewers notice quickly, and this makes it a scored indicator. The comparison is case-insensitive on dataset and variable names.
check_define_consistency( define, data, ctx, source_name = "define_vs_data", source_version = NULL )check_define_consistency( define, data, ctx, source_name = "define_vs_data", source_version = NULL )
define |
Either a path to a Define-XML file, or a data.frame with
|
data |
A data.frame with |
ctx |
|
source_name, source_version
|
Provenance recorded on the evidence. |
A data.frame conforming to the evidence schema, one row per variable
checked, under indicator Q-DEFINE-CONSIST.
define_variables(), define_xml_to_evidence().
ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) define <- data.frame( dataset = c("ADSL", "ADSL", "ADSL"), variable = c("USUBJID", "AGE", "SEX") ) data <- data.frame( dataset = c("ADSL", "ADSL", "ADSL"), variable = c("USUBJID", "AGE", "RACE") # SEX missing, RACE undocumented ) ev <- suppressMessages(check_define_consistency(define, data, ctx)) ev[, c("asset_id", "result", "message")]ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) define <- data.frame( dataset = c("ADSL", "ADSL", "ADSL"), variable = c("USUBJID", "AGE", "SEX") ) data <- data.frame( dataset = c("ADSL", "ADSL", "ADSL"), variable = c("USUBJID", "AGE", "RACE") # SEX missing, RACE undocumented ) ev <- suppressMessages(check_define_consistency(define, data, ctx)) ev[, c("asset_id", "result", "message")]
Returns one row per variable declared in Define-XML, following the
ItemGroupDef to ItemRef to ItemDef structure: the dataset name comes
from the ItemGroupDef, and the variable name from the ItemDef its
ItemRef points at. Elements are matched by local name, so the result does
not depend on how the file mixes the ODM and def: namespaces.
define_variables(file)define_variables(file)
file |
Path to a Define-XML file. |
A data.frame with columns dataset and variable.
Reads a Define-XML 2.0/2.1 file and extracts dataset, variable, and derivation completeness checks into the standard evidence table format. Three indicators are evaluated for each asset:
Dataset is present and has a non-empty label.
Variable is documented (has label and dataType).
Derivation text is present for derived variables.
define_xml_to_evidence(file, ctx, source_version = "2.1")define_xml_to_evidence(file, ctx, source_version = "2.1")
file |
Character. Path to a Define-XML file ( |
ctx |
An r4sub_run_context providing run and study metadata. |
source_version |
Character. Version label for the Define-XML standard.
Default: |
A data.frame conforming to the evidence schema, one row per dataset-level check (Q-DEFINE-001), per variable check (Q-DEFINE-002), and per derivation check (Q-DEFINE-003).
# Build a minimal Define-XML 2.1 document xml_txt <- '<?xml version="1.0" encoding="UTF-8"?> <ODM xmlns="http://www.cdisc.org/ns/odm/v1.3" xmlns:def="http://www.cdisc.org/ns/def/v2.1"> <Study OID="STUDY001"> <MetaDataVersion OID="MDV.001" Name="Define-XML 2.1"> <def:ItemGroupDef OID="IG.ADSL" Name="ADSL" SASDatasetName="ADSL" Repeating="No" Purpose="Analysis" def:Label="Subject-Level Analysis Dataset"> <ItemRef ItemOID="IT.ADSL.USUBJID" Mandatory="Yes"/> <ItemRef ItemOID="IT.ADSL.AGE" Mandatory="Yes"/> </def:ItemGroupDef> <ItemDef OID="IT.ADSL.USUBJID" Name="USUBJID" DataType="text" Length="20" SASFieldName="USUBJID"> <Description><TranslatedText>Unique Subject Identifier</TranslatedText></Description> </ItemDef> <ItemDef OID="IT.ADSL.AGE" Name="AGE" DataType="integer" Length="8" SASFieldName="AGE"> <Description><TranslatedText>Age</TranslatedText></Description> <def:Origin Type="Derived"> <def:Description><TranslatedText>Derived from RFSTDTC</TranslatedText></def:Description> </def:Origin> </ItemDef> </MetaDataVersion> </Study> </ODM>' tmp <- tempfile(fileext = ".xml") writeLines(xml_txt, tmp) ctx <- r4sub_run_context("STUDY001", "DEV") ev <- define_xml_to_evidence(tmp, ctx) nrow(ev)# Build a minimal Define-XML 2.1 document xml_txt <- '<?xml version="1.0" encoding="UTF-8"?> <ODM xmlns="http://www.cdisc.org/ns/odm/v1.3" xmlns:def="http://www.cdisc.org/ns/def/v2.1"> <Study OID="STUDY001"> <MetaDataVersion OID="MDV.001" Name="Define-XML 2.1"> <def:ItemGroupDef OID="IG.ADSL" Name="ADSL" SASDatasetName="ADSL" Repeating="No" Purpose="Analysis" def:Label="Subject-Level Analysis Dataset"> <ItemRef ItemOID="IT.ADSL.USUBJID" Mandatory="Yes"/> <ItemRef ItemOID="IT.ADSL.AGE" Mandatory="Yes"/> </def:ItemGroupDef> <ItemDef OID="IT.ADSL.USUBJID" Name="USUBJID" DataType="text" Length="20" SASFieldName="USUBJID"> <Description><TranslatedText>Unique Subject Identifier</TranslatedText></Description> </ItemDef> <ItemDef OID="IT.ADSL.AGE" Name="AGE" DataType="integer" Length="8" SASFieldName="AGE"> <Description><TranslatedText>Age</TranslatedText></Description> <def:Origin Type="Derived"> <def:Description><TranslatedText>Derived from RFSTDTC</TranslatedText></def:Description> </def:Origin> </ItemDef> </MetaDataVersion> </Study> </ODM>' tmp <- tempfile(fileext = ".xml") writeLines(xml_txt, tmp) ctx <- r4sub_run_context("STUDY001", "DEV") ev <- define_xml_to_evidence(tmp, ctx) nrow(ev)
Reports what changed between two evidence tables, for example the same submission checked at two points in time. Rows are matched on a key (by default the indicator applied to a specific asset) and classified as added, removed, changed, or unchanged, with a direction that says whether each change made the submission better or worse.
evidence_diff( old, new, key = c("indicator_id", "asset_id"), include_unchanged = FALSE )evidence_diff( old, new, key = c("indicator_id", "asset_id"), include_unchanged = FALSE )
old, new
|
Valid evidence data.frames, as produced by |
key |
Character vector of columns that identify a comparable row.
Default |
include_unchanged |
Logical. If |
When a key appears on more than one row within a table (an indicator that
emits several messages for the same asset, say), the rows are collapsed to
the worst one for that key before comparison: lowest result score first
(fail beats warn beats pass), then highest severity. This keeps the
diff at the indicator level, which is what a submission team acts on.
A data.frame with the key columns plus indicator_name,
indicator_domain, change (added, removed, changed, or
unchanged), direction (improved, regressed, or neutral),
result_from, result_to, severity_from, severity_to,
metric_from, and metric_to. Rows are ordered with the most actionable
first: regressions, then new findings, then resolved findings, then
improvements. The returned object carries a "summary" attribute with the
count in each change category.
ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) mk <- function(id, result, severity) { suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = id, indicator_name = id, indicator_domain = "quality", severity = severity, result = result, stringsAsFactors = FALSE ), ctx = ctx )) } old <- suppressMessages(bind_evidence(mk("A", "fail", "high"), mk("B", "pass", "low"))) new <- suppressMessages(bind_evidence(mk("A", "pass", "high"), mk("C", "fail", "medium"))) evidence_diff(old, new)ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) mk <- function(id, result, severity) { suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = id, indicator_name = id, indicator_domain = "quality", severity = severity, result = result, stringsAsFactors = FALSE ), ctx = ctx )) } old <- suppressMessages(bind_evidence(mk("A", "fail", "high"), mk("B", "pass", "low"))) new <- suppressMessages(bind_evidence(mk("A", "pass", "high"), mk("C", "fail", "medium"))) evidence_diff(old, new)
Returns the column specification for the R4SUB evidence table. Each element describes a column's expected R type and, where applicable, the set of allowed values.
evidence_schema()evidence_schema()
A named list. Each element is a list with type (character) and
optionally allowed (character vector) or nullable (logical).
str(evidence_schema())str(evidence_schema())
Returns the R4SUB evidence schema as a tidy table: one row per column with
its type, whether it is required, the controlled vocabulary (when the column
has one), and a short description. This is the published, machine-readable
form of the schema that evidence_schema() encodes, suitable for
documentation, a data dictionary, or a Define-XML style reference.
evidence_schema_spec()evidence_schema_spec()
A tibble with columns column, type, required,
allowed_values, and description. allowed_values is a comma-separated
string, or NA when the column is free text.
evidence_schema_spec()evidence_schema_spec()
The evidence table carries a schema version so a table written by one release
of the ecosystem can be recognized, validated, and migrated by another.
evidence_schema_version() with no argument returns the version this release
writes. Given an evidence table, it returns the version stamped on that table,
or NA when the table predates versioning.
evidence_schema_version(x = NULL)evidence_schema_version(x = NULL)
x |
Optional. An evidence data.frame. When supplied, the stamped version of that table is returned instead of the current package version. |
A single version string, or NA_character_ for an unstamped table.
migrate_evidence() to upgrade an older table.
evidence_schema_version() ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) evidence_schema_version(ev)evidence_schema_version() ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) evidence_schema_version(ev)
A reference table of the evidence sources R4SUB can ingest, their status, the format they come from, and the pillar they feed. Use it to see at a glance what is wired up today and what is on the roadmap.
evidence_sources()evidence_sources()
A tibble with columns source, status, format, pillar, and
entry_point.
evidence_sources()evidence_sources()
Returns a summary data.frame with counts grouped by domain, severity, result, and source.
evidence_summary(ev)evidence_summary(ev)
ev |
A valid evidence data.frame. |
A data.frame with columns: indicator_domain, severity, result,
source_name, and n.
ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) evidence_summary(ev)ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) evidence_summary(ev)
Validates the evidence table then writes it to disk in the requested format.
Metadata attributes (exported_at, r4subcore_version, nrow) are
attached to the returned path value for traceability.
export_evidence(evidence, file, format = c("csv", "rds", "json"))export_evidence(evidence, file, format = c("csv", "rds", "json"))
evidence |
A valid evidence data.frame (as produced by |
file |
Character. Destination file path (including extension). |
format |
Character. One of |
Invisibly returns file with attributes:
POSIXct timestamp of export.
Package version string.
Number of rows written.
ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) tmp_csv <- tempfile(fileext = ".csv") out <- suppressMessages(export_evidence(ev, tmp_csv, format = "csv")) file.exists(out)ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) tmp_csv <- tempfile(fileext = ".csv") out <- suppressMessages(export_evidence(ev, tmp_csv, format = "csv")) file.exists(out)
Creates a deterministic hash from one or more character inputs, hashed in
memory with rlang::hash().
hash_id(..., prefix = NULL)hash_id(..., prefix = NULL)
... |
Character values to hash together. Concatenated with |
prefix |
Optional prefix prepended to the hash (e.g., |
A character string of the form prefix-hexhash or just hexhash.
hash_id("ADSL", "rule_001") hash_id("my_study", "2024-01-01", prefix = "RUN")hash_id("ADSL", "rule_001") hash_id("my_study", "2024-01-01", prefix = "RUN")
Reads an evidence table that was previously saved by export_evidence(),
then validates it against the evidence schema.
import_evidence(file, format = c("csv", "rds", "json"))import_evidence(file, format = c("csv", "rds", "json"))
file |
Character. Path to the file to read. |
format |
Character. One of |
A validated evidence data.frame conforming to the evidence schema.
ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) tmp_rds <- tempfile(fileext = ".rds") suppressMessages(export_evidence(ev, tmp_rds, format = "rds")) ev2 <- suppressMessages(import_evidence(tmp_rds, format = "rds")) nrow(ev2)ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) tmp_rds <- tempfile(fileext = ".rds") suppressMessages(export_evidence(ev, tmp_rds, format = "rds")) ev2 <- suppressMessages(import_evidence(tmp_rds, format = "rds")) nrow(ev2)
Converts an R object to a valid JSON string. Returns "{}" on failure
or for NULL/empty inputs.
json_safely(x)json_safely(x)
x |
An R object to serialize. |
A single character string containing valid JSON.
json_safely(list(a = 1, b = "hello")) json_safely(NULL)json_safely(list(a = 1, b = "hello")) json_safely(NULL)
Upgrades an evidence table written by an older release to the requested schema version, applying each intervening migration step in order. A table with no stamp is treated as the earliest known version. A table already at the target is returned unchanged apart from the version stamp.
migrate_evidence(x, to = current_evidence_schema_version())migrate_evidence(x, to = current_evidence_schema_version())
x |
An evidence data.frame. |
to |
Target schema version. Defaults to the current version. |
The migrated evidence data.frame, stamped with to.
ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) ev <- migrate_evidence(ev) evidence_schema_version(ev)ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) ev <- migrate_evidence(ev) evidence_schema_version(ev)
Applies min-max normalization to a numeric vector, optionally clamping values to [0, 1].
normalize_01(x, direction = c("higher_better", "lower_better"), clamp = TRUE)normalize_01(x, direction = c("higher_better", "lower_better"), clamp = TRUE)
x |
Numeric vector. |
direction |
Character. |
clamp |
Logical. If |
Numeric vector normalized to 0–1.
normalize_01(c(10, 20, 30, 40, 50)) normalize_01(c(10, 20, 30), direction = "lower_better")normalize_01(c(10, 20, 30, 40, 50)) normalize_01(c(10, 20, 30), direction = "lower_better")
Converts a data.frame of Pinnacle21-style validation results into the standard evidence table format. Column names are detected case-insensitively.
p21_to_evidence( p21_df, ctx, asset_type = "validation", source_version = NULL, default_domain = "quality" )p21_to_evidence( p21_df, ctx, asset_type = "validation", source_version = NULL, default_domain = "quality" )
p21_df |
A data.frame containing Pinnacle21 validation output. Expected
columns (case-insensitive): |
ctx |
A r4sub_run_context providing run and study metadata. |
asset_type |
Character. Asset type label. Default: |
source_version |
Character or |
default_domain |
Character. Indicator domain. Default: |
A data.frame conforming to the evidence schema.
p21_raw <- data.frame( Rule = c("SD0001", "SD0002"), Message = c("Missing variable label", "Invalid format"), Severity = c("Error", "Warning"), Dataset = c("ADSL", "ADAE"), Variable = c("AGE", "AESTDTC"), Status = c("Failed", "Warning"), stringsAsFactors = FALSE ) ctx <- r4sub_run_context("STUDY1", "DEV") ev <- p21_to_evidence(p21_raw, ctx)p21_raw <- data.frame( Rule = c("SD0001", "SD0002"), Message = c("Missing variable label", "Invalid format"), Severity = c("Error", "Warning"), Dataset = c("ADSL", "ADAE"), Variable = c("AGE", "AESTDTC"), Status = c("Failed", "Warning"), stringsAsFactors = FALSE ) ctx <- r4sub_run_context("STUDY1", "DEV") ev <- p21_to_evidence(p21_raw, ctx)
A run context captures metadata for a particular evidence collection run.
It provides a unique run_id, study identifier, environment label, and
timestamps used throughout evidence ingestion.
r4sub_run_context( study_id, environment = c("DEV", "UAT", "PROD"), user = NULL, run_id = NULL, timestamp = Sys.time() )r4sub_run_context( study_id, environment = c("DEV", "UAT", "PROD"), user = NULL, run_id = NULL, timestamp = Sys.time() )
study_id |
Character. Study identifier (e.g., |
environment |
Character. One of |
user |
Character or |
run_id |
Character or |
timestamp |
POSIXct. Defaults to current time. |
A list of class r4sub_run_context with elements:
run_id, study_id, environment, user, created_at.
ctx <- r4sub_run_context(study_id = "STUDY001", environment = "DEV") ctx$run_id ctx$study_idctx <- r4sub_run_context(study_id = "STUDY001", environment = "DEV") ctx$run_id ctx$study_id
Loads a Pinnacle 21 validation report (the export most teams already produce
for every submission) into a data.frame, ready for p21_to_evidence(). CSV
exports are read with base R. Excel exports are read with the readxl
package when it is installed; if it is not, export the report as CSV instead.
read_p21_report(path, format = c("auto", "csv", "xlsx"), sheet = NULL)read_p21_report(path, format = c("auto", "csv", "xlsx"), sheet = NULL)
path |
Path to the report file. |
format |
One of |
sheet |
For Excel reports, the sheet to read. When |
This function only reads the file; it does not interpret the columns. Pass the
result to p21_to_evidence(), which detects the rule, message, severity,
dataset, variable, and result columns case-insensitively.
A data.frame of the report rows with the original column names.
p21_to_evidence() to convert the result into evidence.
# Simulate a small CSV export and read it back. p21 <- data.frame( "Rule ID" = c("SD0001", "SD0002"), Message = c("Missing variable label", "Invalid format"), Severity = c("Error", "Warning"), Dataset = c("ADSL", "ADAE"), Variable = c("AGEU", "AESEQ"), Status = c("Failed", "Warning"), check.names = FALSE ) csv <- tempfile(fileext = ".csv") utils::write.csv(p21, csv, row.names = FALSE) report <- read_p21_report(csv) report# Simulate a small CSV export and read it back. p21 <- data.frame( "Rule ID" = c("SD0001", "SD0002"), Message = c("Missing variable label", "Invalid format"), Severity = c("Error", "Warning"), Dataset = c("ADSL", "ADAE"), Variable = c("AGEU", "AESEQ"), Status = c("Failed", "Warning"), check.names = FALSE ) csv <- tempfile(fileext = ".csv") utils::write.csv(p21, csv, row.names = FALSE) report <- read_p21_report(csv) report
Adds an indicator definition to the local in-memory registry.
register_indicator( indicator_id, domain, description, expected_inputs = character(0), default_thresholds = numeric(0), tags = character(0) )register_indicator( indicator_id, domain, description, expected_inputs = character(0), default_thresholds = numeric(0), tags = character(0) )
indicator_id |
Character. Stable identifier for the indicator. |
domain |
Character. One of |
description |
Character. Human-readable description. |
expected_inputs |
Character vector. Evidence source types this indicator expects. |
default_thresholds |
Named numeric vector. Optional thresholds. |
tags |
Character vector. Optional tags (e.g., |
The indicator definition list, invisibly.
register_indicator( indicator_id = "P21-001", domain = "quality", description = "Required variable is missing from dataset" )register_indicator( indicator_id = "P21-001", domain = "quality", description = "Required variable is missing from dataset" )
Converts canonical result labels to numeric scores.
result_to_score(result)result_to_score(result)
result |
Character vector of canonical result values
( |
Numeric vector: pass=1, warn=0.5, fail=0, na=NA.
result_to_score(c("pass", "fail", "warn", "na"))result_to_score(c("pass", "fail", "warn", "na"))
Converts canonical severity labels to numeric penalty multipliers on a 0–1 scale.
severity_to_weight(severity)severity_to_weight(severity)
severity |
Character vector of canonical severity values
( |
Default mapping:
info = 0.00
low = 0.25
medium = 0.50
high = 0.75
critical = 1.00
Numeric vector of weights.
severity_to_weight(c("low", "high", "critical"))severity_to_weight(c("low", "high", "critical"))
Checks that a data.frame conforms to the evidence schema. Verifies column presence, types, and controlled vocabulary values.
validate_evidence(ev)validate_evidence(ev)
ev |
A data.frame to validate. |
TRUE invisibly if valid; throws an error otherwise.
ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) validate_evidence(ev)ctx <- suppressMessages(r4sub_run_context("STUDY1", "DEV")) ev <- suppressMessages(as_evidence( data.frame( asset_type = "validation", asset_id = "ADSL", source_name = "pinnacle21", indicator_id = "SD0001", indicator_name = "SD0001", indicator_domain = "quality", severity = "high", result = "fail", stringsAsFactors = FALSE ), ctx = ctx )) validate_evidence(ev)
Checks that an indicator definition list is well-formed.
validate_indicator(indicator)validate_indicator(indicator)
indicator |
A list with required fields: |
TRUE invisibly if valid; throws an error otherwise.
validate_indicator(list( indicator_id = "P21-001", domain = "quality", description = "Missing required variable" ))validate_indicator(list( indicator_id = "P21-001", domain = "quality", description = "Missing required variable" ))