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: flag each subject's baseline pain score (ABLFL), mark a baseline
taken from the screening questionnaire instead of the protocol's baseline
visit (SCBLFL), and carry the baseline score (BASE) and the change from
it (CHG), alongside each subject's treatment start date (TRTSDT).
Input: collected questionnaire records of a single-item worst-pain rating
from 0 to 10, at screening, Cycle 1 Day 1 and Cycle 2 Day 1, each with its
visit number (VISITNUM), completion date and numeric result, which is
empty when the questionnaire was not done; plus subject-level treatment
start dates.
Variables:
ADTis the questionnaire record's collection date, kept when the questionnaire was not done; empty when the visit was not attended.TRTSDTis the subject's treatment start date.AVALis the collected rating; empty when the questionnaire was not done.ABLFLisYon the Cycle 1 Day 1 record when it has a rating and was completed on or before the treatment start date. When it has no rating or was completed after the first dose,ABLFLisYon the screening record instead, if that has a rating. Blank on every other record, and on every record of a subject with neither.SCBLFL(Screening Used as Baseline Flag) isYon the baseline record when it is the screening record; blank on every other record, including a Cycle 1 Day 1 baseline.BASEis the baseline rating, repeated on every record of the subject and parameter; empty when the subject has no baseline.CHGisAVALminusBASEon each record completed after the treatment start date; empty on the baseline record and every other record on or before that date, and whereverAVALorBASEis empty.
Note: the protocol schedules the baseline questionnaire on Cycle 1 Day 1, before the first dose, and only it or the screening questionnaire can be the baseline, so a later rating never stands in. The screening record itself carries both flags; no separate baseline record is added.
Inputs
Under review2 source filesinput/adsl.csv
Edit4 rows| STUDYID | USUBJID | TRTSDT |
|---|---|---|
| YAMAA-01 | 2025-02-03 | |
| YAMAA-01 | 2025-02-10 | |
| YAMAA-01 | 2025-02-17 | |
| YAMAA-01 | 2025-02-24 |
input/qs.csv
Edit12 rows| STUDYID | USUBJID | QSSEQ | QSCAT | QSTESTCD | QSTEST | QSSTRESN | QSSTAT | VISITNUM | VISIT | QSDTC |
|---|---|---|---|---|---|---|---|---|---|---|
| YAMAA-01 | 1 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | 6 | — | 1 | SCREENING | 2025-01-20 | |
| YAMAA-01 | 2 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | 5 | — | 2 | CYCLE 1 DAY 1 | 2025-02-03 | |
| YAMAA-01 | 3 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | 3 | — | 3 | CYCLE 2 DAY 1 | 2025-02-24 | |
| YAMAA-01 | 1 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | 7 | — | 1 | SCREENING | 2025-01-27 | |
| YAMAA-01 | 2 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | — | NOT DONE | 2 | CYCLE 1 DAY 1 | 2025-02-10 | |
| YAMAA-01 | 3 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | 4 | — | 3 | CYCLE 2 DAY 1 | 2025-03-03 | |
| YAMAA-01 | 1 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | — | NOT DONE | 1 | SCREENING | 2025-02-03 | |
| YAMAA-01 | 2 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | — | NOT DONE | 2 | CYCLE 1 DAY 1 | — | |
| YAMAA-01 | 3 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | 5 | — | 3 | CYCLE 2 DAY 1 | 2025-03-10 | |
| YAMAA-01 | 1 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | 4 | — | 1 | SCREENING | 2025-02-10 | |
| YAMAA-01 | 2 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | 6 | — | 2 | CYCLE 1 DAY 1 | 2025-02-25 | |
| YAMAA-01 | 3 | PAIN NUMERIC RATING SCALE | PAIN01 | Worst Pain in the Last 24 Hours | 5 | — | 3 | CYCLE 2 DAY 1 | 2025-03-17 |
Expected output
Under review12 expected rowsexpected/adqs.csv
Edit12 rows| STUDYID | USUBJID | PARAMCD | PARAM | VISITNUM | VISIT | ADT | TRTSDT | AVAL | ABLFL | SCBLFL | BASE | CHG |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 1 | SCREENING | 2025-01-20 | 2025-02-03 | 6 | — | — | 5 | — | |
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 2 | CYCLE 1 DAY 1 | 2025-02-03 | 2025-02-03 | 5 | Y | — | 5 | — | |
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 3 | CYCLE 2 DAY 1 | 2025-02-24 | 2025-02-03 | 3 | — | — | 5 | -2 | |
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 1 | SCREENING | 2025-01-27 | 2025-02-10 | 7 | Y | Y | 7 | — | |
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 2 | CYCLE 1 DAY 1 | 2025-02-10 | 2025-02-10 | — | — | — | 7 | — | |
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 3 | CYCLE 2 DAY 1 | 2025-03-03 | 2025-02-10 | 4 | — | — | 7 | -3 | |
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 1 | SCREENING | 2025-02-03 | 2025-02-17 | — | — | — | — | — | |
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 2 | CYCLE 1 DAY 1 | — | 2025-02-17 | — | — | — | — | — | |
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 3 | CYCLE 2 DAY 1 | 2025-03-10 | 2025-02-17 | 5 | — | — | — | — | |
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 1 | SCREENING | 2025-02-10 | 2025-02-24 | 4 | Y | Y | 4 | — | |
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 2 | CYCLE 1 DAY 1 | 2025-02-25 | 2025-02-24 | 6 | — | — | 4 | 2 | |
| YAMAA-01 | PAIN01 | Worst Pain in the Last 24 Hours | 3 | CYCLE 2 DAY 1 | 2025-03-17 | 2025-02-24 | 5 | — | — | 4 | 1 |
Human review and assessment
| Dataset Name | Variable Name | Variable Label | Type | Codelist/Controlled Terms | Core | Computational Method | Origin |
|---|---|---|---|---|---|---|---|
| ADQS | STUDYID | Study Identifier | character | Copy value from QS.STUDYID. | Predecessor | ||
| ADQS | USUBJID | Unique Subject Identifier | character | Copy value from QS.USUBJID. | Predecessor | ||
| ADQS | PARAMCD | Parameter Code | character | Copy value from QS.QSTESTCD. | Predecessor | ||
| ADQS | PARAM | Parameter | character | Copy value from QS.QSTEST. | Predecessor | ||
| ADQS | VISITNUM | Visit Number | numeric | Copy value from QS.VISITNUM. | Predecessor | ||
| ADQS | VISIT | Visit Name | character | Copy value from QS.VISIT. | Predecessor | ||
| ADQS | ADT | Analysis Date | numeric | ISO 8601 | Copy value from QS.QSDTC. | Predecessor | |
| ADQS | TRTSDT | Date of First Exposure to Treatment | numeric | ISO 8601 | Copy value from ADSL.TRTSDT. | Predecessor | |
| ADQS | AVAL | Analysis Value | numeric | Copy value from QS.QSSTRESN. | Predecessor | ||
| ADQS | ABLFL | Baseline Record Flag | character | "Y" for the last record with ADT on or before TRTSDT and a non-missing AVAL within each group of STUDYID, USUBJID, PARAMCD, ordered by ADT; blank otherwise. | Derived | ||
| ADQS | SCBLFL | Screening Used as Baseline Flag | character | "Y" when ABLFL = 'Y' AND VISIT = 'SCREENING'; blank otherwise. | Derived | ||
| ADQS | BASE | Baseline Value | numeric | Aggregate ONLY(AVAL) over records grouped by STUDYID, USUBJID, PARAMCD, matching on the shared output keys, where ABLFL = 'Y'. | Derived | ||
| ADQS | CHG | Change from Baseline | numeric | If ADT > TRTSDT then compute AVAL - BASE; otherwise "None". | Derived |
| 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/adam-adqs-screening-baseline/full.md
Edit33 linesFollowing CDISC ADaM standards, use the provided ADSL and QS datasets to create an ADQS dataset with one record per subject per parameter per visit.
The output dataset should contain the following columns in this order: STUDYID, USUBJID, PARAMCD, PARAM, VISITNUM, VISIT, ADT, TRTSDT, AVAL, ABLFL, SCBLFL, BASE, CHG
PARAMCD and PARAM are the collected QSTESTCD and QSTEST, unchanged. ADT is the date in QSDTC, also on a record whose questionnaire was not done; it has no value where QSDTC is empty, as when the visit was not attended. TRTSDT is the subject's treatment start date. AVAL is the collected rating, QSSTRESN, and has no value when the questionnaire was not done.
- ABLFL is "Y" on the "CYCLE 1 DAY 1" record when it has a rating and its ADT is on or before TRTSDT. When that record has no rating or is dated after TRTSDT, ABLFL is "Y" on the "SCREENING" record instead, if that has a rating. When neither applies, the subject has no baseline. ABLFL has no value on every other record.
- Only those two visits can be the baseline; a "CYCLE 2 DAY 1" rating never stands in.
- SCBLFL (Screening Used as Baseline Flag) is "Y" on the baseline record when it is the "SCREENING" record, and has no value on every other record, a "CYCLE 1 DAY 1" baseline included. The screening record itself carries both flags; no separate baseline record is added.
- BASE is the baseline record's AVAL, on every record of the subject and parameter, and has no value for a subject without a baseline.
- CHG is AVAL minus BASE on each record whose ADT is after TRTSDT, a "CYCLE 1 DAY 1" record included. CHG has no value on the baseline record and every other record dated on or before TRTSDT, and wherever AVAL or BASE has no value.
Read the source datasets from /app/input and save the completed dataset as /app/output/adqs.csv.
prompts/adam-adqs-screening-baseline/conventions.md
Edit13 linesFollowing CDISC ADaM standards, use the provided ADSL and QS datasets to create an ADQS dataset with one record per subject per parameter per visit.
The output dataset should contain the following columns in this order: STUDYID, USUBJID, PARAMCD, PARAM, VISITNUM, VISIT, ADT, TRTSDT, AVAL, ABLFL, SCBLFL, BASE, CHG
PARAMCD and PARAM are the collected QSTESTCD and QSTEST, unchanged. ABLFL is "Y" or has no value. SCBLFL (Screening Used as Baseline Flag) is "Y" or has no value.
Read the source datasets from /app/input and save the completed dataset as /app/output/adqs.csv.
prompts/adam-adqs-screening-baseline/brief.md
Edit9 linesFollowing CDISC ADaM standards, use the provided ADSL and QS datasets to create an ADQS dataset with one record per subject per parameter per visit.
The output dataset should contain the following columns in this order: STUDYID, USUBJID, PARAMCD, PARAM, VISITNUM, VISIT, ADT, TRTSDT, AVAL, ABLFL, SCBLFL, BASE, CHG
Read the source datasets from /app/input and save the completed dataset as /app/output/adqs.csv.
R
Edit3 lineslibrary(yamaa)yamaa_spec("spec.yaml")$run()$outputPython
Edit3 linesimport yamaayamaa.spec("spec.yaml").run().outputsolutions/adam-adqs-screening-baseline/result.R
Edit87 lines# Reference solution for the yamaa benchmark adam-adqs-screening-baseline (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.suppressPackageStartupMessages({ library(dplyr) library(readr)})adsl <- read_csv( "/app/input/adsl.csv", col_types = cols(.default = col_character()), na = character(), progress = FALSE) |> mutate(TRTSDT = as.Date(na_if(TRTSDT, ""))) |> select(STUDYID, USUBJID, TRTSDT)qs <- read_csv( "/app/input/qs.csv", col_types = cols(.default = col_character()), na = character(), progress = FALSE) |> mutate( QSSTRESN = as.numeric(na_if(QSSTRESN, "")), VISITNUM = as.numeric(VISITNUM), QSDTC = na_if(QSDTC, "") )# One record per subject, parameter and visit, with the subject's treatment# start date. The rating is the collected result, and it is missing when the# questionnaire was not done. ADT is the collected date, not-done records# included.adqs <- qs |> left_join(adsl, by = c("STUDYID", "USUBJID")) |> transmute( STUDYID, USUBJID, PARAMCD = QSTESTCD, PARAM = QSTEST, VISITNUM, VISIT, ADT = as.Date(substr(QSDTC, 1, 10)), TRTSDT, AVAL = QSSTRESN )# A record can be the baseline only when it has a rating. Cycle 1 Day 1 counts# when dated on or before the treatment start date; otherwise screening counts.has_rating <- !is.na(adqs$AVAL)c1d1_ok <- adqs$VISIT == "CYCLE 1 DAY 1" & has_rating & !is.na(adqs$ADT) & !is.na(adqs$TRTSDT) & adqs$ADT <= adqs$TRTSDTscr_ok <- adqs$VISIT == "SCREENING" & has_ratingadqs <- adqs |> mutate(.c1d1_ok = c1d1_ok, .scr_ok = scr_ok) |> group_by(USUBJID, PARAMCD) |> mutate( .use_c1d1 = any(.c1d1_ok), ABLFL = case_when( .use_c1d1 & .c1d1_ok ~ "Y", !.use_c1d1 & .scr_ok ~ "Y", TRUE ~ NA_character_ ), SCBLFL = if_else(!is.na(ABLFL) & VISIT == "SCREENING", "Y", NA_character_), BASE = if (any(!is.na(ABLFL))) AVAL[which(!is.na(ABLFL))[1]] else NA_real_ ) |> ungroup() |> mutate( CHG = if_else( !is.na(ADT) & !is.na(TRTSDT) & ADT > TRTSDT & !is.na(AVAL) & !is.na(BASE), AVAL - BASE, NA_real_ ) ) |> arrange(USUBJID, PARAMCD, VISITNUM) |> select( STUDYID, USUBJID, PARAMCD, PARAM, VISITNUM, VISIT, ADT, TRTSDT, AVAL, ABLFL, SCBLFL, BASE, CHG )dir.create("/app/output", showWarnings = FALSE, recursive = TRUE)write_csv(adqs, "/app/output/adqs.csv", na = "")solutions/adam-adqs-screening-baseline/result.py
Edit103 lines# Reference solution for the yamaa benchmark adam-adqs-screening-baseline (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 pathlib import Pathimport polars as plINPUT = Path("/app/input")OUTPUT = Path("/app/output")KEYS = ["STUDYID", "USUBJID", "PARAMCD"]COLUMNS = [ "STUDYID", "USUBJID", "PARAMCD", "PARAM", "VISITNUM", "VISIT", "ADT", "TRTSDT", "AVAL", "ABLFL", "SCBLFL", "BASE", "CHG",]adsl = pl.read_csv(INPUT / "adsl.csv", infer_schema_length=0).select( "STUDYID", "USUBJID", pl.col("TRTSDT").str.strip_chars().replace("", None).str.to_date("%Y-%m-%d", strict=False),)qs = pl.read_csv(INPUT / "qs.csv", infer_schema_length=0)adqs = ( qs.select( "STUDYID", "USUBJID", pl.col("QSTESTCD").alias("PARAMCD"), pl.col("QSTEST").alias("PARAM"), pl.col("VISITNUM").cast(pl.Int64), "VISIT", # ISO 8601 date part of QSDTC; empty when the visit date is not collected. pl.col("QSDTC").str.strip_chars().replace("", None) .str.slice(0, 10).str.to_date("%Y-%m-%d", strict=False).alias("ADT"), pl.col("QSSTRESN").str.strip_chars().replace("", None) .cast(pl.Float64).alias("AVAL"), ) .join(adsl, on=["STUDYID", "USUBJID"], how="left"))has_rating = pl.col("AVAL").is_not_null()on_or_before_trt = ( pl.col("ADT").is_not_null() & pl.col("TRTSDT").is_not_null() & (pl.col("ADT") <= pl.col("TRTSDT")))c1d1_ok = (pl.col("VISIT") == "CYCLE 1 DAY 1") & has_rating & on_or_before_trtscr_ok = (pl.col("VISIT") == "SCREENING") & has_ratingadqs = adqs.with_columns( c1d1_ok.any().over(KEYS).alias("_C1D1_BASE"),)adqs = adqs.with_columns( pl.when(c1d1_ok | (~pl.col("_C1D1_BASE") & scr_ok)) .then(pl.lit("Y")) .otherwise(pl.lit(None, dtype=pl.String)) .alias("ABLFL"),)adqs = adqs.with_columns( pl.when((pl.col("ABLFL") == "Y") & (pl.col("VISIT") == "SCREENING")) .then(pl.lit("Y")) .otherwise(pl.lit(None, dtype=pl.String)) .alias("SCBLFL"), pl.col("AVAL").filter(pl.col("ABLFL") == "Y").first().over(KEYS).alias("BASE"),)adqs = adqs.with_columns( pl.when( pl.col("ADT").is_not_null() & pl.col("TRTSDT").is_not_null() & (pl.col("ADT") > pl.col("TRTSDT")) & pl.col("ABLFL").is_null() ) .then(pl.col("AVAL") - pl.col("BASE")) .otherwise(None) .alias("CHG"),)def as_text(name: str) -> pl.Expr: """Render a numeric value without a trailing '.0' when it is whole.""" col = pl.col(name) return ( pl.when(col.is_null()) .then(None) .when(col == col.round(0)) .then(col.round(0).cast(pl.Int64).cast(pl.String)) .otherwise(col.cast(pl.String)) .alias(name) )adqs = ( adqs.sort(["STUDYID", "USUBJID", "PARAMCD", "VISITNUM"]) .with_columns(as_text("AVAL"), as_text("BASE"), as_text("CHG")) .select(COLUMNS))OUTPUT.mkdir(parents=True, exist_ok=True)adqs.write_csv(OUTPUT / "adqs.csv", date_format="%Y-%m-%d", null_value="")solutions/adam-adqs-screening-baseline/result.sas
Edit106 lines/* opensas reference solution for the yamaa benchmark adam-adqs-screening-baseline. Reads the benchmark inputs and derives the requested output. Execute with the existing opensas runtime: opensas /app/output/result.sas. */data adsl; length STUDYID USUBJID TRTSDT $1024; infile "/app/input/adsl.csv" dsd dlm="," firstobs=2 truncover lrecl=32767; input STUDYID : $char1024. USUBJID : $char1024. TRTSDT : $char1024.;run;/* ISO dates are kept as text, so they compare in date order. A not-done questionnaire has no rating. */data qs; length STUDYID USUBJID QSCAT PARAMCD PARAM QSSTAT VISIT ADT $1024; infile "/app/input/qs.csv" dsd dlm="," firstobs=2 truncover lrecl=32767; input STUDYID : $char1024. USUBJID : $char1024. QSSEQ QSCAT : $char1024. PARAMCD : $char1024. PARAM : $char1024. AVAL QSSTAT : $char1024. VISITNUM VISIT : $char1024. ADT : $char1024.; if upcase(QSSTAT) = "NOT DONE" then AVAL = .;run;/* Treatment start date from ADSL on every QS record. */proc sql; create table qs2 as select a.STUDYID, a.USUBJID, a.PARAMCD, a.PARAM, a.VISITNUM, a.VISIT, a.ADT, b.TRTSDT, a.AVAL from qs as a left join adsl as b on a.STUDYID = b.STUDYID and a.USUBJID = b.USUBJID;quit;proc sort data=qs2; by STUDYID USUBJID PARAMCD VISITNUM;run;/* One row per subject and parameter that has a baseline: the CYCLE 1 DAY 1 rating dated on or before TRTSDT, otherwise the SCREENING rating. */data basesel; set qs2; by STUDYID USUBJID PARAMCD; length BLVISIT $20; retain c1d1ok scrok c1d1val scrval; if first.PARAMCD then do; c1d1ok = 0; scrok = 0; c1d1val = .; scrval = .; end; if VISIT = "CYCLE 1 DAY 1" and not missing(AVAL) and not missing(ADT) and not missing(TRTSDT) and ADT <= TRTSDT then do; c1d1ok = 1; c1d1val = AVAL; end; if VISIT = "SCREENING" and not missing(AVAL) then do; scrok = 1; scrval = AVAL; end; if last.PARAMCD then do; if c1d1ok = 1 then do; BLVISIT = "CYCLE 1 DAY 1"; BASE = c1d1val; output; end; else if scrok = 1 then do; BLVISIT = "SCREENING"; BASE = scrval; output; end; end; keep STUDYID USUBJID PARAMCD BLVISIT BASE;run;proc sql; create table combined as select a.*, b.BLVISIT, b.BASE from qs2 as a left join basesel as b on a.STUDYID = b.STUDYID and a.USUBJID = b.USUBJID and a.PARAMCD = b.PARAMCD;quit;/* Flags, BASE on every record of the subject and parameter, and CHG on the non-baseline records dated after TRTSDT. */data adqs1; set combined; length ABLFL SCBLFL $1; ABLFL = ""; SCBLFL = ""; if not missing(BLVISIT) and VISIT = BLVISIT then do; ABLFL = "Y"; if VISIT = "SCREENING" then SCBLFL = "Y"; end; CHG = .; if ABLFL ne "Y" and not missing(AVAL) and not missing(BASE) and not missing(ADT) and not missing(TRTSDT) and ADT > TRTSDT then CHG = AVAL - BASE;run;proc sql; create table adqs as select STUDYID, USUBJID, PARAMCD, PARAM, VISITNUM, VISIT, ADT, TRTSDT, AVAL, ABLFL, SCBLFL, BASE, CHG from adqs1 order by STUDYID, USUBJID, PARAMCD, VISITNUM;quit;proc export data=adqs outfile="/app/output/adqs.csv" dbms=csv replace;run;
yamaa