Moves non-standard variables out of a parent domain into the vertical SUPP-- structure the SDTMIG requires: STUDYID, RDOMAIN, USUBJID, IDVAR, IDVARVAL, QNAM, QLABEL, QORIG, QEVAL, QVAL.

make_supp(domain, spec)

Arguments

domain

The parent domain data frame. Needs USUBJID and the columns named in the spec; STUDYID and DOMAIN are used when present.

spec

Either a character vector of QNAMs, or a data frame with a QNAM column and any of QLABEL, QORIG, QEVAL, IDVAR. Missing QLABEL defaults to QNAM, missing QORIG to "CRF".

Value

An sdtmgap_domain tibble in SUPPQUAL structure, sorted by USUBJID, IDVAR, IDVARVAL, QNAM.

Details

IDVAR comes from the spec. When the spec does not name one, it defaults to the parent domain's --SEQ if that column exists (record-level qualifier), and to blank if it does not — which is what makes SUPPDM, whose qualifiers are subject-level, come out right without being told.

Records whose QVAL is missing or blank are dropped, as the standard requires: SUPPQUAL carries values, not placeholders. A QNAM longer than 8 characters or a QVAL longer than 200 warns rather than errors, so the dataset is still produced and the problem is visible.

The parent domain is returned untouched; drop the moved columns yourself with dplyr::select(domain, -dplyr::any_of(spec$QNAM)).

SAS idiom replaced. The per-QNAM DATA step block — one output-per-variable stanza, IDVARVAL = put(--SEQ, best.), then PROC SORT NODUPKEY — copied and edited for every study.

Examples

# Record-level: IDVAR defaults to VSSEQ
make_supp(
  sdtmgap_example("edge_vs"),
  data.frame(
    QNAM = "VSCLSIG",
    QLABEL = "Clinically Significant",
    QORIG = "CRF",
    QEVAL = "INVESTIGATOR"
  )
)
#> 
#> ── SDTM SUPPVS (3 records) ─────────────────────────────────────────────────────
#>  3 qualifier record(s) from 1 variable(s) on 3 subject(s).
#>  29 record(s) dropped for missing QVAL.
#> # A tibble: 3 × 10
#>   STUDYID   RDOMAIN USUBJID       IDVAR IDVARVAL QNAM   QLABEL QORIG QEVAL QVAL 
#> * <chr>     <chr>   <chr>         <chr> <chr>    <chr>  <chr>  <chr> <chr> <chr>
#> 1 SDTMGAP01 VS      SDTMGAP01-001 VSSEQ 4        VSCLS… Clini… CRF   INVE… Y    
#> 2 SDTMGAP01 VS      SDTMGAP01-003 VSSEQ 1        VSCLS… Clini… CRF   INVE… Y    
#> 3 SDTMGAP01 VS      SDTMGAP01-005 VSSEQ 4        VSCLS… Clini… CRF   INVE… Y    

# Subject-level: DM has no DMSEQ, so IDVAR comes out blank
make_supp(sdtmgap_example("edge_dm"), c("RACEOTH", "FASFL"))
#> 
#> ── SDTM SUPPDM (9 records) ─────────────────────────────────────────────────────
#>  9 qualifier record(s) from 2 variable(s) on 7 subject(s).
#>  5 record(s) dropped for missing QVAL.
#> # A tibble: 9 × 10
#>   STUDYID   RDOMAIN USUBJID       IDVAR IDVARVAL QNAM   QLABEL QORIG QEVAL QVAL 
#> * <chr>     <chr>   <chr>         <chr> <chr>    <chr>  <chr>  <chr> <chr> <chr>
#> 1 SDTMGAP01 DM      SDTMGAP01-001 ""    ""       FASFL  FASFL  CRF   ""    Y    
#> 2 SDTMGAP01 DM      SDTMGAP01-002 ""    ""       FASFL  FASFL  CRF   ""    Y    
#> 3 SDTMGAP01 DM      SDTMGAP01-003 ""    ""       FASFL  FASFL  CRF   ""    Y    
#> 4 SDTMGAP01 DM      SDTMGAP01-003 ""    ""       RACEO… RACEO… CRF   ""    MIXE…
#> 5 SDTMGAP01 DM      SDTMGAP01-004 ""    ""       FASFL  FASFL  CRF   ""    Y    
#> 6 SDTMGAP01 DM      SDTMGAP01-005 ""    ""       FASFL  FASFL  CRF   ""    N    
#> 7 SDTMGAP01 DM      SDTMGAP01-006 ""    ""       FASFL  FASFL  CRF   ""    Y    
#> 8 SDTMGAP01 DM      SDTMGAP01-006 ""    ""       RACEO… RACEO… CRF   ""    PREF…
#> 9 SDTMGAP01 DM      SDTMGAP01-007 ""    ""       FASFL  FASFL  CRF   ""    N