As a clinical trial statistician or programmer, answer three short questions in Your review: the task, the inputs and outputs, and the AI-assisted review. Agreeing with all three approves this benchmark; disagreeing with any needs a comment. Propose a fix with the Edit button on any source file, or add it to your comments.
We suggest spending no more than 5 minutes on a review. The other tabs beside Your review are background for assessment, not under review.
Summary
README.mdPublic entries: Python and R. Passing coverage requires an installed inventory.
Goal: pick the reference range the way a multi-lab study does -- by
lab, test, sex and age band, and by the period the range was in effect --
and flag each result: LBSTNRLO, LBSTNRHI, and LBNRIND.
Input: lab results as Operational Data Model (ODM) item data -- one row
per collected item, with the test code, the collecting lab, the collection
date and the numeric result as IT.LB.* items of a repeating IG.LB panel,
and recorded sex and birth date as IT.DM.* items -- plus a reference
dictionary keyed by lab, test code, sex and age band, each entry carrying the
dates it was in effect, the unit and the lower and upper limits.
Variables:
LBTESTCDis the test code from theIT.LB.LBTESTCDitem.SEXis recorded sex from theIT.DM.SEXitem.LBNAMis the collecting lab from theIT.LB.LBNAMitem; different labs may carry different ranges for the same test.LBSTRESNis the numeric result in standard units from theIT.LB.LBSTRESNitem; missing when the result was not collected.LBORRESUis the unit of the reference entry for the result's lab, test code and sex whose age band holds the subject's age at collection and which was in effect on the collection date; blank, like both limits, when no entry matches.LBSTNRLOis the lower reference limit in standard units from that entry.LBSTNRHIis the upper reference limit in standard units from that entry.LBNRINDisLOWwhen the result is below the lower limit,HIGHwhen it is above the upper limit, andNORMALotherwise; blank when the result or either reference limit is missing.
Note: when a lab revises a range, the entry in effect on the collection
date wins -- a result collected on the first day of the new range is judged
against the new limits -- and a subject whose age falls on an age-band
boundary takes the band that starts at that age. Each output row is built
from one IT.LB.LBDTC item, with the other items of its panel read
alongside; LBSEQ is the panel's repeat key.
Inputs
Under review2 source filesinput/lbrange.csv
Edit10 rows| LBNAM | LBTESTCD | SEX | AGELO | AGEHI | EFFSTDT | EFFENDT | UNIT | NRLO | NRHI |
|---|---|---|---|---|---|---|---|---|---|
| Central Lab | ALT | M | 18 | 99 | 2024-01-01 | 2025-06-30 | U/L | 0 | 40 |
| Central Lab | ALT | M | 18 | 99 | 2025-07-01 | — | U/L | 0 | 45 |
| Central Lab | ALT | F | 18 | 99 | 2024-01-01 | 2025-06-30 | U/L | 0 | 40 |
| Central Lab | ALT | F | 18 | 99 | 2025-07-01 | — | U/L | 0 | 38 |
| Central Lab | CREAT | M | 18 | 99 | 2024-01-01 | — | mg/dL | 0.7 | 1.3 |
| Local Lab A | HGB | F | 0 | 17 | 2024-01-01 | — | g/dL | 11.5 | 15.5 |
| Local Lab A | HGB | F | 18 | 99 | 2024-01-01 | — | g/dL | 12 | 16 |
| Local Lab A | HGB | M | 0 | 17 | 2024-01-01 | — | g/dL | 12 | 16.5 |
| Local Lab A | HGB | M | 18 | 99 | 2024-01-01 | — | g/dL | 13.5 | 17.5 |
| Local Lab A | POTASSIUM | F | 18 | 99 | 2024-01-01 | — | mmol/L | 3.5 | 5.1 |
input/odm.csv
Edit48 rows| StudyOID | MetaDataVersionOID | SubjectKey | StudyEventOID | StudyEventRepeatKey | ItemGroupOID | ItemGroupRepeatKey | ItemOID | Value |
|---|---|---|---|---|---|---|---|---|
| PILOT7 | MDV.1 | P7-501 | SCREENING | 1 | IG.DM | 1 | IT.DM.SEX | M |
| PILOT7 | MDV.1 | P7-501 | SCREENING | 1 | IG.DM | 1 | IT.DM.BRTHDTC | 1980-05-01 |
| PILOT7 | MDV.1 | P7-501 | LAB | 1 | IG.LB | 1 | IT.LB.LBTESTCD | ALT |
| PILOT7 | MDV.1 | P7-501 | LAB | 1 | IG.LB | 1 | IT.LB.LBNAM | Central Lab |
| PILOT7 | MDV.1 | P7-501 | LAB | 1 | IG.LB | 1 | IT.LB.LBDTC | 2025-03-15 |
| PILOT7 | MDV.1 | P7-501 | LAB | 1 | IG.LB | 1 | IT.LB.LBSTRESN | 15 |
| PILOT7 | MDV.1 | P7-502 | SCREENING | 1 | IG.DM | 1 | IT.DM.SEX | F |
| PILOT7 | MDV.1 | P7-502 | SCREENING | 1 | IG.DM | 1 | IT.DM.BRTHDTC | 1990-02-10 |
| PILOT7 | MDV.1 | P7-502 | LAB | 1 | IG.LB | 1 | IT.LB.LBTESTCD | ALT |
| PILOT7 | MDV.1 | P7-502 | LAB | 1 | IG.LB | 1 | IT.LB.LBNAM | Central Lab |
| PILOT7 | MDV.1 | P7-502 | LAB | 1 | IG.LB | 1 | IT.LB.LBDTC | 2025-07-01 |
| PILOT7 | MDV.1 | P7-502 | LAB | 1 | IG.LB | 1 | IT.LB.LBSTRESN | 39 |
| PILOT7 | MDV.1 | P7-503 | SCREENING | 1 | IG.DM | 1 | IT.DM.SEX | F |
| PILOT7 | MDV.1 | P7-503 | SCREENING | 1 | IG.DM | 1 | IT.DM.BRTHDTC | 2017-09-20 |
| PILOT7 | MDV.1 | P7-503 | LAB | 1 | IG.LB | 1 | IT.LB.LBTESTCD | HGB |
| PILOT7 | MDV.1 | P7-503 | LAB | 1 | IG.LB | 1 | IT.LB.LBNAM | Local Lab A |
| PILOT7 | MDV.1 | P7-503 | LAB | 1 | IG.LB | 1 | IT.LB.LBDTC | 2025-02-01 |
| PILOT7 | MDV.1 | P7-503 | LAB | 1 | IG.LB | 1 | IT.LB.LBSTRESN | 12.5 |
| PILOT7 | MDV.1 | P7-504 | SCREENING | 1 | IG.DM | 1 | IT.DM.SEX | M |
| PILOT7 | MDV.1 | P7-504 | SCREENING | 1 | IG.DM | 1 | IT.DM.BRTHDTC | 2007-06-01 |
| PILOT7 | MDV.1 | P7-504 | LAB | 1 | IG.LB | 1 | IT.LB.LBTESTCD | HGB |
| PILOT7 | MDV.1 | P7-504 | LAB | 1 | IG.LB | 1 | IT.LB.LBNAM | Local Lab A |
| PILOT7 | MDV.1 | P7-504 | LAB | 1 | IG.LB | 1 | IT.LB.LBDTC | 2025-06-01 |
| PILOT7 | MDV.1 | P7-504 | LAB | 1 | IG.LB | 1 | IT.LB.LBSTRESN | 12.5 |
| PILOT7 | MDV.1 | P7-505 | SCREENING | 1 | IG.DM | 1 | IT.DM.SEX | M |
| PILOT7 | MDV.1 | P7-505 | SCREENING | 1 | IG.DM | 1 | IT.DM.BRTHDTC | 1975-11-11 |
| PILOT7 | MDV.1 | P7-505 | LAB | 1 | IG.LB | 1 | IT.LB.LBTESTCD | CREAT |
| PILOT7 | MDV.1 | P7-505 | LAB | 1 | IG.LB | 1 | IT.LB.LBNAM | Central Lab |
| PILOT7 | MDV.1 | P7-505 | LAB | 1 | IG.LB | 1 | IT.LB.LBDTC | 2025-04-01 |
| PILOT7 | MDV.1 | P7-505 | LAB | 1 | IG.LB | 1 | IT.LB.LBSTRESN | 0.9 |
| PILOT7 | MDV.1 | P7-506 | SCREENING | 1 | IG.DM | 1 | IT.DM.SEX | M |
| PILOT7 | MDV.1 | P7-506 | SCREENING | 1 | IG.DM | 1 | IT.DM.BRTHDTC | 1988-03-03 |
| PILOT7 | MDV.1 | P7-506 | LAB | 1 | IG.LB | 1 | IT.LB.LBTESTCD | ALT |
| PILOT7 | MDV.1 | P7-506 | LAB | 1 | IG.LB | 1 | IT.LB.LBNAM | Central Lab |
| PILOT7 | MDV.1 | P7-506 | LAB | 1 | IG.LB | 1 | IT.LB.LBDTC | 2025-08-01 |
| PILOT7 | MDV.1 | P7-506 | LAB | 1 | IG.LB | 1 | IT.LB.LBSTRESN | — |
| PILOT7 | MDV.1 | P7-507 | SCREENING | 1 | IG.DM | 1 | IT.DM.SEX | F |
| PILOT7 | MDV.1 | P7-507 | SCREENING | 1 | IG.DM | 1 | IT.DM.BRTHDTC | 1995-12-12 |
| PILOT7 | MDV.1 | P7-507 | LAB | 1 | IG.LB | 1 | IT.LB.LBTESTCD | POTASSIUM |
| PILOT7 | MDV.1 | P7-507 | LAB | 1 | IG.LB | 1 | IT.LB.LBNAM | Local Lab A |
| PILOT7 | MDV.1 | P7-507 | LAB | 1 | IG.LB | 1 | IT.LB.LBDTC | 2025-05-05 |
| PILOT7 | MDV.1 | P7-507 | LAB | 1 | IG.LB | 1 | IT.LB.LBSTRESN | 5.5 |
| PILOT7 | MDV.1 | P7-508 | SCREENING | 1 | IG.DM | 1 | IT.DM.SEX | M |
| PILOT7 | MDV.1 | P7-508 | SCREENING | 1 | IG.DM | 1 | IT.DM.BRTHDTC | 1980-01-01 |
| PILOT7 | MDV.1 | P7-508 | LAB | 1 | IG.LB | 1 | IT.LB.LBTESTCD | GLUCOSE |
| PILOT7 | MDV.1 | P7-508 | LAB | 1 | IG.LB | 1 | IT.LB.LBNAM | Central Lab |
| PILOT7 | MDV.1 | P7-508 | LAB | 1 | IG.LB | 1 | IT.LB.LBDTC | 2025-05-05 |
| PILOT7 | MDV.1 | P7-508 | LAB | 1 | IG.LB | 1 | IT.LB.LBSTRESN | 5 |
Expected output
Under review8 expected rowsexpected/lb.csv
Edit8 rows| DOMAIN | STUDYID | USUBJID | LBSEQ | LBTESTCD | SEX | LBNAM | LBSTRESN | LBORRESU | LBSTNRLO | LBSTNRHI | LBNRIND |
|---|---|---|---|---|---|---|---|---|---|---|---|
| LB | PILOT7 | 1 | ALT | M | Central Lab | 15 | U/L | 0 | 40 | NORMAL | |
| LB | PILOT7 | 1 | ALT | F | Central Lab | 39 | U/L | 0 | 38 | HIGH | |
| LB | PILOT7 | 1 | HGB | F | Local Lab A | 12.5 | g/dL | 11.5 | 15.5 | NORMAL | |
| LB | PILOT7 | 1 | HGB | M | Local Lab A | 12.5 | g/dL | 13.5 | 17.5 | LOW | |
| LB | PILOT7 | 1 | CREAT | M | Central Lab | 0.9 | mg/dL | 0.7 | 1.3 | NORMAL | |
| LB | PILOT7 | 1 | ALT | M | Central Lab | — | U/L | 0 | 45 | — | |
| LB | PILOT7 | 1 | POTASSIUM | F | Local Lab A | 5.5 | mmol/L | 3.5 | 5.1 | HIGH | |
| LB | PILOT7 | 1 | GLUCOSE | M | Central Lab | 5 | — | — | — | — |
Human review and assessment
| Variable Name | Variable Label | Type | Length | Controlled Terms or Format | Origin | Core | Conversion Definition | Variable Type | Variable Order | Comments for Define |
|---|---|---|---|---|---|---|---|---|---|---|
| DOMAIN | Domain Abbreviation | Char | Assigned | Set constant value "LB". | SDTM | 1 | ||||
| STUDYID | Study Identifier | Char | Collected | Copy value from ODM.StudyOID. | SDTM | 2 | ||||
| USUBJID | Unique Subject Identifier | Char | Collected | Copy value from ODM.SubjectKey. | SDTM | 3 | ||||
| LBSEQ | Sequence Number | Num | Collected | Copy value from ODM.ItemGroupRepeatKey. | SDTM | 4 | ||||
| LBTESTCD | Lab Test or Examination Short Name | Char | Derived | Take Value from the ODM record whose StudyOID equals ODM.StudyOID, SubjectKey equals ODM.SubjectKey, StudyEventOID equals ODM.StudyEventOID, ItemGroupOID equals ODM.ItemGroupOID and ItemGroupRepeatKey equals ODM.ItemGroupRepeatKey, where ODM.ItemOID = 'IT.LB.LBTESTCD', and a row with no match is an error. | SDTM | 5 | ||||
| SEX | Sex | Char | Derived | Take Value from the ODM record whose StudyOID equals ODM.StudyOID and SubjectKey equals ODM.SubjectKey, where ODM.ItemOID = 'IT.DM.SEX', and a row with no match is an error. | SDTM | 6 | ||||
| LBNAM | Lab Name | Char | Derived | Take Value from the ODM record whose StudyOID equals ODM.StudyOID, SubjectKey equals ODM.SubjectKey, StudyEventOID equals ODM.StudyEventOID, ItemGroupOID equals ODM.ItemGroupOID and ItemGroupRepeatKey equals ODM.ItemGroupRepeatKey, where ODM.ItemOID = 'IT.LB.LBNAM', and a row with no match is an error. | SDTM | 7 | ||||
| LBSTRESN | Numeric Result/Finding in Standard Units | Num | Derived | Take Value from the ODM record whose StudyOID equals ODM.StudyOID, SubjectKey equals ODM.SubjectKey, StudyEventOID equals ODM.StudyEventOID, ItemGroupOID equals ODM.ItemGroupOID and ItemGroupRepeatKey equals ODM.ItemGroupRepeatKey, where ODM.ItemOID = 'IT.LB.LBSTRESN', and a row with no match is an error. | SDTM | 8 | ||||
| LBORRESU | Original Units | Char | Derived | Take UNIT from the LBRANGE record matching on LBNAM, LBTESTCD and SEX, where AGE falls within AGELO to AGEHI, where LBRANGE.EFFSTDT <= ODM.Value AND (LBRANGE.EFFENDT IS NULL OR ODM.Value <= LBRANGE.EFFENDT), and no match yields blank. | SDTM | 9 | ||||
| LBSTNRLO | Reference Range Lower Limit-Std Units | Num | Derived | Take NRLO from the LBRANGE record matching on LBNAM, LBTESTCD and SEX, where AGE falls within AGELO to AGEHI, where LBRANGE.EFFSTDT <= ODM.Value AND (LBRANGE.EFFENDT IS NULL OR ODM.Value <= LBRANGE.EFFENDT), and no match yields blank. | SDTM | 10 | ||||
| LBSTNRHI | Reference Range Upper Limit-Std Units | Num | Derived | Take NRHI from the LBRANGE record matching on LBNAM, LBTESTCD and SEX, where AGE falls within AGELO to AGEHI, where LBRANGE.EFFSTDT <= ODM.Value AND (LBRANGE.EFFENDT IS NULL OR ODM.Value <= LBRANGE.EFFENDT), and no match yields blank. | SDTM | 11 | ||||
| LBNRIND | Reference Range Indicator | Char | Derived | If LBSTRESN IS NULL OR LBSTNRLO IS NULL OR LBSTNRHI IS NULL then "None"; If LBSTRESN < LBSTNRLO then "LOW"; If LBSTRESN > LBSTNRHI then "HIGH"; otherwise "NORMAL". | SDTM | 12 |
| Template | Include when |
|---|---|
| result | ODM.ItemOID = 'IT.LB.LBDTC' |
| Version | Date | Author | Description | Reviewer | Sign-off |
|---|---|---|---|---|---|
| 1.7 | 2026-10-20 | yamaa docs build | Read a specification in the 1.0 surface as its 0.5 counterpart; state that missing values stay missing where a mapping declares no missing handler, and leave out a declared missing answer that restates a handler's default | ||
| 1.6 | 2026-10-17 | yamaa docs build | Describe collected date parts written as ISO 8601 date text and times of day counted in seconds since midnight | ||
| 1.5 | 2026-10-17 | yamaa docs build | Name collected precision in words instead of letter codes; state imputation fallbacks, minimum source precision, bounds ignored outside the collected period, and invalid text with no handler as an error; describe date and datetime shifts, imputation flag codes, and partial text giving no date part | ||
| 1.4 | 2026-10-15 | yamaa docs build | State datetime precision codes through the hour and minute, and complete only the time parts a collected datetime lacks | ||
| 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/sdtm-lb-lab-specific-ranges/full.md
Edit32 linesFollowing CDISC SDTM standards, use the provided LBRANGE and ODM datasets to create an LB dataset with one record per collected lab result.
The output dataset should contain the following columns in this order: DOMAIN, STUDYID, USUBJID, LBSEQ, LBTESTCD, SEX, LBNAM, LBSTRESN, LBORRESU, LBSTNRLO, LBSTNRHI, LBNRIND
DOMAIN is "LB". STUDYID is the ODM study OID and USUBJID is the ODM subject key, each as given. Each record is built from one IT.LB.LBDTC item of a lab panel, with the panel's other items read alongside it, and LBSEQ is the panel's repeat key. LBTESTCD is the test code from the IT.LB.LBTESTCD item. SEX is the recorded sex from the IT.DM.SEX item. LBNAM is the collecting lab from the IT.LB.LBNAM item. LBSTRESN is the numeric result in standard units from the IT.LB.LBSTRESN item, with no value when the result was not collected. The reference entry for a result is the LBRANGE entry for the result's lab, test code, and sex whose age band holds the subject's age in whole years at collection, counted from the subject's birth date to the collection date, and which was in effect on the collection date. A subject whose age falls on an age-band boundary takes the band that starts at that age. An entry is in effect on a date from its first effective date through its last effective date, and an entry with no last effective date remains in effect. When a lab revises a range, the entry in effect on the collection date wins, so a result collected on the first day of the new range is judged against the new limits. LBORRESU is the matched entry's unit, LBSTNRLO is its lower reference limit in standard units, and LBSTNRHI is its upper reference limit in standard units; all three have no value when no entry matches. LBNRIND is "LOW" when the result is below the lower limit, "HIGH" when it is above the upper limit, and "NORMAL" otherwise, and it has no value when the result or either reference limit is missing.
Read the source datasets from /app/input and save the completed dataset as /app/output/lb.csv.
prompts/sdtm-lb-lab-specific-ranges/conventions.md
Edit13 linesFollowing CDISC SDTM standards, use the provided LBRANGE and ODM datasets to create an LB dataset with one record per collected lab result.
The output dataset should contain the following columns in this order: DOMAIN, STUDYID, USUBJID, LBSEQ, LBTESTCD, SEX, LBNAM, LBSTRESN, LBORRESU, LBSTNRLO, LBSTNRHI, LBNRIND
DOMAIN is "LB". The subject's age counts in whole years at collection, counted from the subject's birth date to the collection date. LBNRIND is "LOW", "HIGH", or "NORMAL", or has no value.
Read the source datasets from /app/input and save the completed dataset as /app/output/lb.csv.
prompts/sdtm-lb-lab-specific-ranges/brief.md
Edit9 linesFollowing CDISC SDTM standards, use the provided LBRANGE and ODM datasets to create an LB dataset with one record per collected lab result.
The output dataset should contain the following columns in this order: DOMAIN, STUDYID, USUBJID, LBSEQ, LBTESTCD, SEX, LBNAM, LBSTRESN, LBORRESU, LBSTNRLO, LBSTNRHI, LBNRIND
Read the source datasets from /app/input and save the completed dataset as /app/output/lb.csv.
R
Edit3 lineslibrary(yamaa)yamaa_spec("spec.yaml")$run()$outputPython
Edit3 linesimport yamaayamaa.spec("spec.yaml").run().outputsolutions/sdtm-lb-lab-specific-ranges/result.R
Edit117 lines# Reference solution for the yamaa benchmark sdtm-lb-lab-specific-ranges (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)library(tidyr)library(purrr)library(lubridate)odm <- read_csv( "/app/input/odm.csv", col_types = cols(.default = col_character())) |> mutate(Value = na_if(Value, ""))lbrange <- read_csv( "/app/input/lbrange.csv", col_types = cols( AGELO = col_integer(), AGEHI = col_integer(), NRLO = col_double(), NRHI = col_double(), .default = col_character() ))age_years <- function(birth, collected) { b <- ymd(birth) c <- ymd(collected) years <- year(c) - year(b) before_birthday <- (month(c) < month(b)) | (month(c) == month(b) & day(c) < day(b)) years - if_else(before_birthday, 1L, 0L)}dm <- odm |> filter(ItemGroupOID == "IG.DM") |> select(SubjectKey, ItemOID, Value) |> pivot_wider(names_from = ItemOID, values_from = Value)labs <- odm |> filter(ItemGroupOID == "IG.LB") |> distinct(StudyOID, SubjectKey, ItemGroupRepeatKey)one_lab <- function(study, subj, igrep) { sub <- odm |> filter( SubjectKey == subj, ItemGroupOID == "IG.LB", ItemGroupRepeatKey == igrep ) get <- function(oid) { hit <- sub |> filter(ItemOID == oid) if (nrow(hit) == 0) return(NA_character_) hit$Value[[1]] } dsub <- dm |> filter(SubjectKey == subj) sex <- if (nrow(dsub) == 0) NA_character_ else dsub$`IT.DM.SEX`[[1]] birth <- if (nrow(dsub) == 0) NA_character_ else dsub$`IT.DM.BRTHDTC`[[1]] code <- get("IT.LB.LBTESTCD") lbnam <- get("IT.LB.LBNAM") lbdtc <- get("IT.LB.LBDTC") raw <- get("IT.LB.LBSTRESN") stresn <- suppressWarnings(as.numeric(raw)) unit <- NA_character_ lo <- NA_real_ hi <- NA_real_ if (!is.na(birth) && !is.na(lbdtc) && !is.na(code) && !is.na(lbnam) && !is.na(sex)) { age <- age_years(birth, lbdtc) hit <- lbrange |> filter( LBNAM == lbnam, LBTESTCD == code, SEX == sex, AGELO <= age, age < AGEHI, EFFSTDT <= lbdtc, is.na(EFFENDT) | lbdtc <= EFFENDT ) |> arrange(desc(EFFSTDT), desc(AGELO)) |> slice_head(n = 1) if (nrow(hit) == 1) { unit <- hit$UNIT[[1]] lo <- hit$NRLO[[1]] hi <- hit$NRHI[[1]] } } nrind <- if (is.na(stresn) || is.na(lo) || is.na(hi)) { NA_character_ } else if (stresn < lo) { "LOW" } else if (stresn > hi) { "HIGH" } else { "NORMAL" } tibble( DOMAIN = "LB", STUDYID = study, USUBJID = subj, LBSEQ = as.integer(igrep), LBTESTCD = code, SEX = sex, LBNAM = lbnam, LBSTRESN = stresn, LBORRESU = unit, LBSTNRLO = lo, LBSTNRHI = hi, LBNRIND = nrind )}lb <- pmap_dfr( list(labs$StudyOID, labs$SubjectKey, labs$ItemGroupRepeatKey), one_lab) |> arrange(STUDYID, USUBJID, LBSEQ)dir.create("/app/output", showWarnings = FALSE)write_csv(lb, "/app/output/lb.csv", na = "")solutions/sdtm-lb-lab-specific-ranges/result.py
Edit123 lines# Reference solution for the yamaa benchmark sdtm-lb-lab-specific-ranges (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.from datetime import datefrom pathlib import Pathimport polars as plodm = pl.read_csv("/app/input/odm.csv", infer_schema=False)lbrange = pl.read_csv("/app/input/lbrange.csv", infer_schema=False).with_columns( pl.col("AGELO").cast(pl.Int64), pl.col("AGEHI").cast(pl.Int64), pl.col("NRLO").cast(pl.Float64, strict=False), pl.col("NRHI").cast(pl.Float64, strict=False),)subjects = {}labs = {}study_of = {}for r in odm.to_dicts(): study_of[r["SubjectKey"]] = r["StudyOID"] if r["ItemGroupOID"] == "IG.DM": subjects.setdefault(r["SubjectKey"], {})[r["ItemOID"]] = ( r["Value"] if r["Value"] not in (None, "") else None ) elif r["ItemGroupOID"] == "IG.LB": key = (r["SubjectKey"], r["ItemGroupRepeatKey"]) labs.setdefault(key, {})[r["ItemOID"]] = ( r["Value"] if r["Value"] not in (None, "") else None )def age_years(birth, collected): b = date.fromisoformat(birth) c = date.fromisoformat(collected) years = c.year - b.year if (c.month, c.day) < (b.month, b.day): years -= 1 return yearsranges = sorted(lbrange.to_dicts(), key=lambda r: (r["EFFSTDT"], r["AGELO"]), reverse=True)rows = []for (subj, repkey), lab in labs.items(): dm = subjects.get(subj, {}) sex = dm.get("IT.DM.SEX") birth = dm.get("IT.DM.BRTHDTC") code = lab.get("IT.LB.LBTESTCD") lbnam = lab.get("IT.LB.LBNAM") lbdtc = lab.get("IT.LB.LBDTC") raw = lab.get("IT.LB.LBSTRESN") try: stresn = float(raw) if raw not in (None, "") else None except ValueError: stresn = None unit = lo = hi = None if birth and lbdtc and code and lbnam and sex: age = age_years(birth, lbdtc) best = None for rg in ranges: if rg["LBNAM"] != lbnam or rg["LBTESTCD"] != code or rg["SEX"] != sex: continue if not (rg["AGELO"] <= age < rg["AGEHI"]): continue eff_start = rg["EFFSTDT"] eff_end = rg["EFFENDT"] if rg["EFFENDT"] not in (None, "") else None if lbdtc < eff_start: continue if eff_end is not None and lbdtc > eff_end: continue best = rg break if best is not None: unit, lo, hi = best["UNIT"], best["NRLO"], best["NRHI"] if stresn is None or lo is None or hi is None: nrind = None elif stresn < lo: nrind = "LOW" elif stresn > hi: nrind = "HIGH" else: nrind = "NORMAL" rows.append( { "DOMAIN": "LB", "STUDYID": study_of[subj], "USUBJID": subj, "LBSEQ": int(repkey), "LBTESTCD": code, "SEX": sex, "LBNAM": lbnam, "LBSTRESN": stresn, "LBORRESU": unit, "LBSTNRLO": lo, "LBSTNRHI": hi, "LBNRIND": nrind, } )lb = pl.DataFrame( rows, schema={ "DOMAIN": pl.String, "STUDYID": pl.String, "USUBJID": pl.String, "LBSEQ": pl.Int64, "LBTESTCD": pl.String, "SEX": pl.String, "LBNAM": pl.String, "LBSTRESN": pl.Float64, "LBORRESU": pl.String, "LBSTNRLO": pl.Float64, "LBSTNRHI": pl.Float64, "LBNRIND": pl.String, },).sort(["STUDYID", "USUBJID", "LBSEQ"])Path("/app/output").mkdir(parents=True, exist_ok=True)lb.write_csv("/app/output/lb.csv")solutions/sdtm-lb-lab-specific-ranges/result.sas
Edit57 lines/* opensas reference solution for the yamaa benchmark sdtm-lb-lab-specific-ranges. Reads the benchmark inputs and derives the requested output. Execute with the existing opensas runtime: opensas /app/output/result.sas. */data lbrange; length LBNAM LBTESTCD SEX EFFSTDT EFFENDT UNIT $1024; infile "/app/input/lbrange.csv" dsd dlm="," firstobs=2 truncover lrecl=32767; input LBNAM : $char1024. LBTESTCD : $char1024. SEX : $char1024. AGELO AGEHI EFFSTDT : $char1024. EFFENDT : $char1024. UNIT : $char1024. NRLO NRHI; RANGE_ORDER=_n_;run;data odm; length StudyOID MetaDataVersionOID SubjectKey StudyEventOID StudyEventRepeatKey ItemGroupOID ItemGroupRepeatKey ItemOID Value $1024; infile "/app/input/odm.csv" dsd dlm="," firstobs=2 truncover lrecl=32767; input StudyOID : $char1024. MetaDataVersionOID : $char1024. SubjectKey : $char1024. StudyEventOID : $char1024. StudyEventRepeatKey : $char1024. ItemGroupOID : $char1024. ItemGroupRepeatKey : $char1024. ItemOID : $char1024. Value : $char1024.;run;proc sort data=odm out=ordered; by StudyOID SubjectKey; run;data subjects; length SEX BRTHDTC $1024; retain SEX BRTHDTC; set ordered; where ItemGroupOID='IG.DM'; by StudyOID SubjectKey; if first.SubjectKey then do; SEX=''; BRTHDTC=''; end; if ItemOID='IT.DM.SEX' then SEX=Value; if ItemOID='IT.DM.BRTHDTC' then BRTHDTC=Value; if last.SubjectKey then output;run;proc sort data=odm out=ordered; by StudyOID SubjectKey ItemGroupRepeatKey; run;data panels; length LBDTC LBNAM LBTESTCD RESULTTEXT $1024; retain LBDTC LBNAM LBTESTCD RESULTTEXT; set ordered; where ItemGroupOID='IG.LB'; by StudyOID SubjectKey ItemGroupRepeatKey; if first.ItemGroupRepeatKey then do; LBDTC=''; LBNAM=''; LBTESTCD=''; RESULTTEXT=''; end; if ItemOID='IT.LB.LBDTC' then LBDTC=Value; if ItemOID='IT.LB.LBNAM' then LBNAM=Value; if ItemOID='IT.LB.LBTESTCD' then LBTESTCD=Value; if ItemOID='IT.LB.LBSTRESN' then RESULTTEXT=Value; if last.ItemGroupRepeatKey then output;run;proc sql; create table withbirth as select a.*,b.SEX,b.BRTHDTC from panels a left join subjects b on a.StudyOID=b.StudyOID and a.SubjectKey=b.SubjectKey; quit;data collected; set withbirth; AGE=.; if lengthn(BRTHDTC)=10 and lengthn(LBDTC)=10 then AGE=intck('year',input(BRTHDTC,yymmdd10.),input(LBDTC,yymmdd10.),'continuous'); LBSTRESN=input(RESULTTEXT,?? best32.); LBSEQ=input(ItemGroupRepeatKey,best32.); run;proc sql; create table joined as select a.*,b.UNIT as LBORRESU,b.NRLO as LBSTNRLO,b.NRHI as LBSTNRHI,b.EFFSTDT as RANGE_START,b.AGELO as RANGE_AGE,b.RANGE_ORDER from collected a left join lbrange b on a.LBNAM=b.LBNAM and a.LBTESTCD=b.LBTESTCD and a.SEX=b.SEX and a.AGE>=b.AGELO and a.AGE<b.AGEHI and a.LBDTC>=b.EFFSTDT and (missing(b.EFFENDT) or a.LBDTC<=b.EFFENDT); quit;proc sort data=joined; by StudyOID SubjectKey LBSEQ descending RANGE_START descending RANGE_AGE RANGE_ORDER; run;data selected; set joined; by StudyOID SubjectKey LBSEQ; if first.LBSEQ; run;data result; set selected; length DOMAIN $2 STUDYID USUBJID $1024 LBNRIND $8; DOMAIN='LB'; STUDYID=StudyOID; USUBJID=SubjectKey; LBNRIND=''; if not missing(LBSTRESN) and not missing(LBSTNRLO) and not missing(LBSTNRHI) then do; if LBSTRESN<LBSTNRLO then LBNRIND='LOW'; else if LBSTRESN>LBSTNRHI then LBNRIND='HIGH'; else LBNRIND='NORMAL'; end; run;proc sql; create table final as select DOMAIN, STUDYID, USUBJID, LBSEQ, LBTESTCD, SEX, LBNAM, LBSTRESN, LBORRESU, LBSTNRLO, LBSTNRHI, LBNRIND from result;quit;proc export data=final outfile="/app/output/lb.csv" dbms=csv replace; run;
yamaa