A validation report tells you a rule failed; it does not tell you where the failure lives. trace_findings() resolves every finding to the dataset object it came from, the variable within it, and - when a specification is supplied - the specification row that declares that variable. This is the reconciliation programmers otherwise do by hand, one PROC CONTENTS and one spec lookup at a time.

trace_findings(findings, datasets, spec = NULL)

Arguments

findings

A p21_findings tibble from read_findings(), or any data frame carrying the same canonical columns.

datasets

Named list of data frames, keyed by dataset/domain name (for example list(DM = dm, AE = ae)). Matching is case-insensitive.

spec

Optional specification (define-XML style) as a data frame with at least a dataset column and a variable column; type, length, codelist, core and label are used when present.

Value

The findings tibble, class p21_traced, with the resolution columns joined on: dataset_found, dataset_rows, variable_found, variable_class, variable_label, variable_max_nchar, variable_n_missing, spec_row, spec_type, spec_length, spec_codelist, spec_core, spec_label, resolved and resolution. The datasets and spec are carried as attributes so suggest_fix() can re-read the data.

Details

Findings that cannot be resolved (a domain that was not supplied, or no domain at all) are returned with resolved = FALSE and a reason in resolution. They are never dropped.

Examples

ex <- readRDS(system.file("extdata", "example_study.rds", package = "p21bridge"))
f <- read_findings(system.file("extdata", "findings.csv", package = "p21bridge"))
tr <- trace_findings(f, ex$datasets, spec = ex$spec)
tr
#> 
#> ── p21bridge traced findings ───────────────────────────────────────────────────
#>  12 findings, 9 resolved to a supplied dataset
#> ! 3 unresolved: unresolved: dataset 'VS' not supplied, unresolved: dataset 'ADSL' not supplied, and unresolved: finding reports no domain
#>  Trace depth: dataset+variable+spec 8 | dataset+spec 1 | unresolved: dataset 'ADSL' not supplied 1 | unresolved: dataset 'VS' not supplied 1 | unresolved: finding reports no domain 1
#> # A tibble: 12 × 25
#>    rule_id severity domain variable message            count rule_class category
#>    <chr>   <chr>    <chr>  <chr>    <chr>              <int> <chr>      <chr>   
#>  1 SD0056  Error    DM     RFENDTC  SDTM Required var…     1 SDTM data  Metadata
#>  2 SD1310  Warning  DM     USUBJID  Variable length i…     5 SDTM data  Length  
#>  3 CT2001  Error    DM     SEX      SEX value not fou…     1 Controlle… Termino…
#>  4 CT2001  Error    AE     AESEV    AESEV value not f…     2 Controlle… Termino…
#>  5 SD1011  Error    DM     RFSTDTC  Invalid ISO 8601 …     1 SDTM data  Format  
#>  6 SD1117  Warning  AE     USUBJID  Duplicate records      2 SDTM data  Consist…
#>  7 SD0064  Error    AE     USUBJID  Subject is not pr…     1 SDTM data  Cross-r…
#>  8 SD0002  Error    AE     AESTDTC  NULL value in var…     1 SDTM data  Presence
#>  9 SD1234  Notice   VS     VSORRES  Result value is n…     3 SDTM data  Consist…
#> 10 DD0011  Warning  DM     AGE      Variable label mi…     1 Define-XML Metadata
#> 11 SD1310  Error    ADSL   TRT01P   Variable length i…     4 SDTM data  Length  
#> 12 OD0018  Notice   NA     NA       Define-XML is mis…     1 ODM / def… Metadata
#> # ℹ 17 more variables: dataset_found <lgl>, dataset_name <chr>,
#> #   dataset_rows <int>, variable_found <lgl>, variable_name <chr>,
#> #   variable_class <chr>, variable_label <chr>, variable_max_nchar <int>,
#> #   variable_n_missing <int>, spec_row <int>, spec_type <chr>,
#> #   spec_length <int>, spec_codelist <chr>, spec_core <chr>, spec_label <chr>,
#> #   resolved <lgl>, resolution <chr>
tr[!tr$resolved, c("rule_id", "domain", "resolution")]
#> # A tibble: 3 × 3
#>   rule_id domain resolution                             
#>   <chr>   <chr>  <chr>                                  
#> 1 SD1234  VS     unresolved: dataset 'VS' not supplied  
#> 2 SD1310  ADSL   unresolved: dataset 'ADSL' not supplied
#> 3 OD0018  NA     unresolved: finding reports no domain