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.
- 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.
- Inputs: Do they look like data collected in a real trial, and do they include the situations you would expect to meet in one?
- 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
README.mdGoal: turn each collected body measurement (BMI or WEIGHT)
into one growth-percentile record holding the percentile in AVAL;
the collected records are not kept.
Input: collected measurements carrying the measurement code
(PARAMCD), the collected result (AVAL, stored as text), sex
(SEX), and age in days (AGE); alongside a sex-and-age growth
reference carrying the coefficients L, M, and S for each
measurement code, sex, and age in days.
Variables:
PARAMCD:BMIPCTLfor a collectedBMImeasurement,WGTPCTLfor a collectedWEIGHTmeasurement.PARAM:BMI-for-Age Percentile/Weight-for-Age Percentile, matchingPARAMCD.AVAL: the growth percentile, 100 times the standard normal cumulative probability of the LMS z-score: the collected result divided byM, raised to the powerL, minus 1, all divided byLtimesS. TheL,M, andSare the reference coefficients matched on measurement code, sex, and age in days. A measurement with no matching reference row, or with no collected result, leavesAVALmissing.
Note: a collected result exactly at the reference median (M)
has a z-score of 0 and so a percentile of exactly 50.
Inputs
Under review2 source filesinput/advs_raw.csv
Edit8 rows| STUDYID | USUBJID | AVISIT | PARAMCD | AVAL | AGE | SEX |
|---|---|---|---|---|---|---|
| YAMAA-01 | MONTH 12 | BMI | 16.2 | 365 | F | |
| YAMAA-01 | MONTH 12 | WEIGHT | 9.1 | 365 | F | |
| YAMAA-01 | MONTH 12 | BMI | 17.5 | 365 | M | |
| YAMAA-01 | MONTH 12 | WEIGHT | 10.0 | 365 | M | |
| YAMAA-01 | MONTH 24 | BMI | 17.0 | 730 | F | |
| YAMAA-01 | MONTH 24 | WEIGHT | 12.4 | 730 | F | |
| YAMAA-01 | MONTH 12 | BMI | 16.0 | 365 | F | |
| YAMAA-01 | MONTH 12 | BMI | — | 365 | F |
input/lms_ref.csv
Edit4 rows| PARAMCD | SEX | AGE | L | M | S |
|---|---|---|---|---|---|
| BMI | F | 365 | -0.8 | 16.0 | 0.08 |
| BMI | M | 365 | -0.7 | 16.5 | 0.08 |
| WEIGHT | F | 365 | -0.4 | 9.0 | 0.10 |
| WEIGHT | M | 365 | -0.3 | 9.6 | 0.10 |
Expected output
Under review8 expected rowsexpected/advs.csv
Edit8 rows| STUDYID | USUBJID | AVISIT | PARAMCD | PARAM | AVAL |
|---|---|---|---|---|---|
| YAMAA-01 | MONTH 12 | BMIPCTL | BMI-for-Age Percentile | 56.13971541306226 | |
| YAMAA-01 | MONTH 12 | WGTPCTL | Weight-for-Age Percentile | 54.389623884577375 | |
| YAMAA-01 | MONTH 12 | BMIPCTL | BMI-for-Age Percentile | 76.4411385545167 | |
| YAMAA-01 | MONTH 12 | WGTPCTL | Weight-for-Age Percentile | 65.75296725058702 | |
| YAMAA-01 | MONTH 24 | BMIPCTL | BMI-for-Age Percentile | — | |
| YAMAA-01 | MONTH 24 | WGTPCTL | Weight-for-Age Percentile | — | |
| YAMAA-01 | MONTH 12 | BMIPCTL | BMI-for-Age Percentile | 50 | |
| YAMAA-01 | MONTH 12 | BMIPCTL | BMI-for-Age Percentile | — |
Comments and assessment materials
| Dataset Name | Variable Name | Variable Label | Type | Codelist/Controlled Terms | Core | Computational Method | Origin |
|---|---|---|---|---|---|---|---|
| ADVS | STUDYID | Study Identifier | character | Copy value from ADVS_RAW.STUDYID. | Predecessor | ||
| ADVS | USUBJID | Unique Subject Identifier | character | Copy value from ADVS_RAW.USUBJID. | Predecessor | ||
| ADVS | AVISIT | Analysis Visit | character | Copy value from ADVS_RAW.AVISIT. | Predecessor | ||
| ADVS | PARAMCD | Parameter Code | character | BMIPCTL, WGTPCTL | If ADVS_RAW.PARAMCD = 'BMI' then "BMIPCTL"; If ADVS_RAW.PARAMCD = 'WEIGHT' then "WGTPCTL"; otherwise blank. | Derived | |
| ADVS | PARAM | Parameter | character | If PARAMCD = 'BMIPCTL' then "BMI-for-Age Percentile"; If PARAMCD = 'WGTPCTL' then "Weight-for-Age Percentile"; otherwise blank. | Derived | ||
| ADVS | AVAL | Analysis Value | numeric | Compute 100 * NORMCDF. | Derived |
| Variable | Permitted values |
|---|---|
| PARAMCD | BMIPCTL, WGTPCTL |
| Version | Date | Author | Description | Reviewer | Sign-off |
|---|---|---|---|---|---|
| 1.3 | 2026-09-29 | yamaa docs build | Show study codelist names, external dictionaries, and ISO 8601 formats in variable rows; list the document's codelist values and metadata | ||
| 1.2 | 2026-09-29 | yamaa docs build | Classify ADaM copies from a declared input as Predecessor and recodes as Derived, and SDTM recodes of locally derived columns as Derived | ||
| 1.1 | 2026-09-29 | yamaa docs build | Resolve lookups into the donor record they select, and give every derivation shape a plain-language rule instead of its raw YAML | ||
| 1.0 | yamaa docs build | Initial generation from spec.yaml |
prompts/adam-advs-percentiles/full.md
Edit23 linesFollowing CDISC ADaM standards, use the provided ADVS_RAW and LMS datasets to create an ADVS dataset with one record per subject per visit per parameter.
The output dataset should contain the following columns in this order: STUDYID, USUBJID, AVISIT, PARAMCD, PARAM, AVAL
Turn each collected body measurement into one growth-percentile record; the collected records are not kept. PARAMCD is "BMIPCTL" for a collected "BMI" measurement and "WGTPCTL" for a collected "WEIGHT" measurement, with PARAM "BMI-for-Age Percentile" and "Weight-for-Age Percentile" to match.
AVAL is the growth percentile for the collected result against the reference coefficients L, M, and S matched on measurement code, sex, and age in days: 100 times the standard normal cumulative probability of the LMS z-score ((result / M) ^ L - 1) / (L * S), not rounded. A measurement with no matching reference row, or with no collected result, leaves AVAL with no value. A collected result exactly at the reference median gives 50.
Read the source datasets from /app/input and save the completed dataset as /app/output/advs.csv.
prompts/adam-advs-percentiles/conventions.md
Edit15 linesFollowing CDISC ADaM standards, use the provided ADVS_RAW and LMS datasets to create an ADVS dataset with one record per subject per visit per parameter.
The output dataset should contain the following columns in this order: STUDYID, USUBJID, AVISIT, PARAMCD, PARAM, AVAL
PARAMCD is "BMIPCTL" for a collected "BMI" measurement and "WGTPCTL" for a collected "WEIGHT" measurement, with PARAM "BMI-for-Age Percentile" and "Weight-for-Age Percentile" to match.
AVAL is the growth percentile, not rounded.
Read the source datasets from /app/input and save the completed dataset as /app/output/advs.csv.
prompts/adam-advs-percentiles/brief.md
Edit9 linesFollowing CDISC ADaM standards, use the provided ADVS_RAW and LMS datasets to create an ADVS dataset with one record per subject per visit per parameter.
The output dataset should contain the following columns in this order: STUDYID, USUBJID, AVISIT, PARAMCD, PARAM, AVAL
Read the source datasets from /app/input and save the completed dataset as /app/output/advs.csv.
run.R
Edit4 lineslibrary(yamaa)advs <- yamaa_domain("spec.yaml", environment = "r/environment.yaml")$outputadvsrun.py
Edit4 linesimport yamaaadvs = yamaa.domain("spec.yaml", environment="python/environment.yaml").outputadvssolutions/adam-advs-percentiles/result.R
Edit39 lines# Reference solution for the yamaa benchmark adam-advs-percentiles (R track).## Written from the benchmark's full prompt and its inputs alone, as an agent# would write it. Harbor's oracle agent runs it to check that the prompt can# be solved and that the grader scores a correct answer 1.library(dplyr, warn.conflicts = FALSE)library(readr)raw <- read_csv( "/app/input/advs_raw.csv", col_types = cols(AVAL = col_double(), AGE = col_integer(), .default = col_character()))ref <- read_csv( "/app/input/lms_ref.csv", col_types = cols( AGE = col_integer(), L = col_double(), M = col_double(), S = col_double(), .default = col_character() ))# The growth percentile against the matched L, M, and S coefficients.advs <- raw |> left_join(ref, by = c("PARAMCD", "SEX", "AGE")) |> mutate( Z = case_when( is.na(AVAL) | is.na(L) | is.na(M) | is.na(S) | M == 0 | S == 0 ~ NA_real_, L == 0 ~ log(AVAL / M) / S, .default = ((AVAL / M) ^ L - 1) / (L * S) ), AVAL = 100 * pnorm(Z), PARAMCD = if_else(PARAMCD == "BMI", "BMIPCTL", "WGTPCTL"), PARAM = if_else(PARAMCD == "BMIPCTL", "BMI-for-Age Percentile", "Weight-for-Age Percentile") ) |> arrange(USUBJID, AVISIT, PARAMCD) |> select(STUDYID, USUBJID, AVISIT, PARAMCD, PARAM, AVAL)dir.create("/app/output", showWarnings = FALSE)write_csv(advs, "/app/output/advs.csv", na = "")solutions/adam-advs-percentiles/result.py
Edit68 lines# Reference solution for the yamaa benchmark adam-advs-percentiles (Python track).## Written from the benchmark's full prompt and its inputs alone, as an agent# would write it. Harbor's oracle agent runs it to check that the prompt can# be solved and that the grader scores a correct answer 1.import mathfrom pathlib import Pathimport polars as plraw = pl.read_csv("/app/input/advs_raw.csv", infer_schema=False).with_columns( pl.col("AVAL").cast(pl.Float64, strict=False), pl.col("AGE").cast(pl.Int64, strict=False),)ref = pl.read_csv("/app/input/lms_ref.csv", infer_schema=False).with_columns( pl.col("AGE").cast(pl.Int64, strict=False), pl.col("L").cast(pl.Float64, strict=False), pl.col("M").cast(pl.Float64, strict=False), pl.col("S").cast(pl.Float64, strict=False),)def percentile(aval: float | None, ell: float | None, emm: float | None, ess: float | None) -> float | None: if aval is None or ell is None or emm is None or ess is None: return None if emm == 0 or ess == 0: return None if ell == 0: z = math.log(aval / emm) / ess else: z = ((aval / emm) ** ell - 1) / (ell * ess) return 100 * 0.5 * (1 + math.erf(z / math.sqrt(2)))joined = raw.join(ref, on=["PARAMCD", "SEX", "AGE"], how="left")rows = []for record in joined.sort(["USUBJID", "AVISIT", "PARAMCD"]).iter_rows(named=True): if record["PARAMCD"] == "BMI": out_code, out_label = "BMIPCTL", "BMI-for-Age Percentile" else: out_code, out_label = "WGTPCTL", "Weight-for-Age Percentile" rows.append( { "STUDYID": record["STUDYID"], "USUBJID": record["USUBJID"], "AVISIT": record["AVISIT"], "PARAMCD": out_code, "PARAM": out_label, "AVAL": percentile(record["AVAL"], record["L"], record["M"], record["S"]), } )advs = pl.DataFrame( rows, schema={ "STUDYID": pl.String, "USUBJID": pl.String, "AVISIT": pl.String, "PARAMCD": pl.String, "PARAM": pl.String, "AVAL": pl.Float64, },)Path("/app/output").mkdir(parents=True, exist_ok=True)advs.write_csv("/app/output/advs.csv")solutions/adam-advs-percentiles/result.sas
Edit35 lines/* opensas reference solution for the yamaa benchmark adam-advs-percentiles. Reads the benchmark inputs and derives the requested output. Execute with the existing opensas runtime: opensas /app/output/result.sas. */data advs_raw; length STUDYID USUBJID AVISIT PARAMCD SEX $1024; infile "/app/input/advs_raw.csv" dsd dlm="," firstobs=2 truncover lrecl=32767; input STUDYID : $char1024. USUBJID : $char1024. AVISIT : $char1024. PARAMCD : $char1024. AVAL AGE SEX : $char1024.;run;data lms_ref; length PARAMCD SEX $1024; infile "/app/input/lms_ref.csv" dsd dlm="," firstobs=2 truncover lrecl=32767; input PARAMCD : $char1024. SEX : $char1024. AGE L M S;run;proc sql; create table joined as select a.*,b.L,b.M,b.S from advs_raw as a left join lms_ref as b on a.PARAMCD=b.PARAMCD and a.SEX=b.SEX and a.AGE=b.AGE;quit;data result; length PARAM $40; set joined; value=AVAL; AVAL=.; if not missing(value) and not missing(M) and not missing(L) and not missing(S) then do; if L=0 then z=log(value/M)/S; else z=((value/M)**L-1)/(L*S); AVAL=100*probnorm(z); end; if PARAMCD='BMI' then do; PARAMCD='BMIPCTL'; PARAM='BMI-for-Age Percentile'; end; else if PARAMCD='WEIGHT' then do; PARAMCD='WGTPCTL'; PARAM='Weight-for-Age Percentile'; end;run;proc sql; create table final as select STUDYID, USUBJID, AVISIT, PARAMCD, PARAM, AVAL from result;quit;proc export data=final outfile="/app/output/advs.csv" dbms=csv replace; run;
yamaa
Comments
Signed in with GitHub; saved in repository Discussions