Most clinical programming teams already run Pinnacle 21 on every submission and have the report on disk. That report is the fastest way to get real evidence into R4SUB: there is no table to build by hand. This vignette shows the two steps, reading the report and converting it to the shared evidence table.
A Pinnacle 21 report lists one row per finding: a rule identifier, a message, a severity, the dataset and variable it concerns, and a status. Here we write a small export to a temporary CSV so the vignette is self-contained. Your real CSV or Excel export has the same shape.
p21 <- data.frame(
"Rule ID" = c("SD0001", "SD0002", "AD0018", "SD1077"),
Message = c("Variable label is missing",
"Value not in controlled terminology",
"Expected variable is present",
"Inconsistent value length"),
Severity = c("Error", "Warning", "Notice", "Error"),
Dataset = c("ADSL", "ADAE", "ADSL", "ADLB"),
Variable = c("AGEU", "AESEV", "RACE", "LBORRES"),
Status = c("Failed", "Warning", "Passed", "Failed"),
check.names = FALSE
)
csv <- tempfile(fileext = ".csv")
utils::write.csv(p21, csv, row.names = FALSE)read_p21_report() loads the file. It reads CSV with base
R and Excel through the readxl package when that is
installed. It only reads the file; it does not interpret the columns
yet.
report <- read_p21_report(csv)
#> ℹ Read 4 rows from '/tmp/RtmpTeuQuy/fileaea289aab1.csv'
report
#> Rule ID Message Severity Dataset Variable Status
#> 1 SD0001 Variable label is missing Error ADSL AGEU Failed
#> 2 SD0002 Value not in controlled terminology Warning ADAE AESEV Warning
#> 3 AD0018 Expected variable is present Notice ADSL RACE Passed
#> 4 SD1077 Inconsistent value length Error ADLB LBORRES Failedp21_to_evidence() maps the report onto the evidence
schema shared across the ecosystem. It detects the rule, message,
severity, dataset, variable, and result columns case-insensitively, so
it tolerates the small naming differences between Pinnacle 21 versions.
Pinnacle 21 severities map onto the evidence vocabulary:
Error becomes high, Warning
becomes medium, and Notice becomes
info.
ctx <- r4sub_run_context("STUDY1", "DEV")
#> ℹ Run context created: "R4S-20261011103822-z5v5kso9"
ev <- p21_to_evidence(report, ctx)
#> ℹ Parsed 4 rows from Pinnacle21 output
#> ✔ Evidence table created: 4 rows
ev[, c("indicator_id", "severity", "result", "location")]
#> indicator_id severity result location
#> 1 SD0001 high fail ADSL:AGEU
#> 2 SD0002 medium warn ADAE:AESEV
#> 3 AD0018 info pass ADSL:RACE
#> 4 SD1077 high fail ADLB:LBORRESThe result is an ordinary evidence table. It validates against the
schema, so it scores like any other evidence, and it can be combined
with evidence from other sources (Define-XML, the ADRG, traceability)
with bind_evidence() before computing a Submission
Confidence Index.