Review ask

As a clinical trial statistician or programmer, challenge anything in this benchmark: describe a problem in Comments, or propose a fix with the Edit button on any source file.

  1. Task: Would a real study need this derivation, specified this way? Does it follow CDISC ADaM: variable names, controlled terms, record structure? Flag any rule that is ambiguous or that a sponsor would handle differently.
  2. Inputs: Do they look like data collected in a real trial, and do they include the situations you would expect to meet in one?
  3. Expected output: Would independent QC programming reproduce every value from these inputs and rules?

The other tabs beside Comments are background for assessment, not under review.

Summary

Lifecycle: draftEditUnder review
What this benchmark means
README.md

Goal: summarize each subject's dosing records three ways: a qualified reduction over the dosing table, a filtered and a per-record-derived variant of it, and an unqualified reduction over the built rows that is broadcast back to every row in its treatment group.

Input: DM carries one row per subject with a treatment group (TRTGRP). EX carries the dosing records: subject, sequence, dose, and treatment. Subject 04 has no dosing records; subject 03 has one record whose dose is missing; subject 01 has three records, one with a missing dose.

Aggregations:

  • NDOSE counts dose records (COUNT(EX.*)); NDOSEVAL counts only the records with a dose present (COUNT(EX.EXDOSE)). TOTDOSE, MEANDOSE, and MAXDOSE are the total, mean and largest of the present doses.
  • DRUGDOSE sums only the DRUG records; PLACDOSE sums only the PLACEBO records, so subjects with no placebo record read as missing.
  • TOTDOSE_MG binds each record's dose in milligrams first (a derive step whose second binding reads the first) and then sums the bound values.
  • AVGNDOSE is unqualified: it averages NDOSE over the built rows within each treatment group and broadcasts the result to every row of the group. Subject 04's missing NDOSE is excluded from the average.

Note: a missing dose contributes nothing and never a zero: TOTDOSE for subject 03 is missing while NDOSEVAL is 0. A subject with no records at all (subject 04) reads every qualified reduction as missing, including both counts. An empty group after filtering (PLACDOSE for subject 01) also reads as missing.

Inputs

Under review
2 source files

input/dm.csv

Edit
4 rows
input/dm.csv
USUBJIDTRTGRP
A
A
B
B

input/ex.csv

Edit
6 rows
input/ex.csv
USUBJIDEXSEQEXDOSEEXTRT
1100DRUG
2200DRUG
3—DRUG
1150DRUG
2150PLACEBO
1—DRUG

Expected output

Under review
4 expected rows

expected/adsl.csv

Edit
4 rows
expected/adsl.csv
USUBJIDTRTGRPNDOSENDOSEVALTOTDOSEMEANDOSEMAXDOSEDRUGDOSEPLACDOSETOTDOSE_MGAVGNDOSE
A32300150200300—3000002.5
A223001501501501503000002.5
B10——————1
B————————1
Shaded columns are derived— = missing value

Comments and assessment materials

Comments

Signed in with GitHub; saved in repository Discussions

Mapping spec

Generated from the benchmark YAML; do not edit by hand

Dataset NameVariable NameVariable LabelTypeCodelist/Controlled TermsCoreComputational MethodOrigin
ADSLUSUBJIDUnique Subject IdentifiercharacterCopy value from DM.USUBJID.Predecessor
ADSLTRTGRPTreatment GroupcharacterCopy value from DM.TRTGRP.Predecessor
ADSLNDOSENumber of Dose RecordsnumericAggregate COUNT(EX.*) over records matching on the shared output keys.Derived
ADSLNDOSEVALNumber of Non-missing DosesnumericAggregate COUNT(EX.EXDOSE) over records matching on the shared output keys.Derived
ADSLTOTDOSETotal DosenumericAggregate SUM(EX.EXDOSE) over records matching on the shared output keys.Derived
ADSLMEANDOSEMean DosenumericAggregate MEAN(EX.EXDOSE) over records matching on the shared output keys.Derived
ADSLMAXDOSEMaximum DosenumericAggregate MAX(EX.EXDOSE) over records matching on the shared output keys.Derived
ADSLDRUGDOSETotal Drug DosenumericAggregate SUM(EX.EXDOSE) over records matching on the shared output keys, where EX.EXTRT = 'DRUG'.Derived
ADSLPLACDOSETotal Placebo DosenumericAggregate SUM(EX.EXDOSE) over records matching on the shared output keys, where EX.EXTRT = 'PLACEBO'.Derived
ADSLTOTDOSE_MGTotal Dose in MilligramsnumericAggregate SUM(DOSEMG) over records matching on the shared output keys, with DOSE as EX.EXDOSE, with DOSEMG as compute DOSE * 1000.Derived
ADSLAVGNDOSEMean Dose Records per Treatment GroupnumericAggregate MEAN(NDOSE) over records grouped by TRTGRP, matching on the shared output keys.Derived
VersionDateAuthorDescriptionReviewerSign-off
1.32026-09-29yamaa docs buildShow study codelist names, external dictionaries, and ISO 8601 formats in variable rows; list the document's codelist values and metadata
1.22026-09-29yamaa docs buildClassify ADaM copies from a declared input as Predecessor and recodes as Derived, and SDTM recodes of locally derived columns as Derived
1.12026-09-29yamaa docs buildResolve lookups into the donor record they select, and give every derivation shape a plain-language rule instead of its raw YAML
1.0yamaa docs buildInitial generation from spec.yaml

yamaa code

Runs the yamaa specification; its result must match the expected output

run.R

Edit
4 lines
library(yamaa)adsl <- yamaa_domain("spec.yaml")$outputadsl

run.py

Edit
4 lines
import yamaaadsl = yamaa.yamaa_domain("spec.yaml").outputadsl