Review ask

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

Lifecycle: draftEditUnder review
What this benchmark means
README.md

Public entries: Python and R. Passing coverage requires an installed inventory.

Goal: carry each pharmacokinetic (PK) parameter of a two-period bioequivalence crossover into ADPP with the period's pre-dose concentration (PRECONC), that concentration as a percentage of the period's maximum concentration (PREPCMAX), and the analysis flag (ANL01FL) that leaves a period with carry-over out of the bioequivalence analysis.

Input: PK parameters (PP) with their numeric result (PPSTRESN) and the reference dose time of their period (PPRFTDTC), and PK concentrations (PC) with planned time point (PCTPT), standard result (PCSTRESC, PCSTRESN), status and the reference dose time (PCRFTDTC).

Variables:

  • VISITNUM and VISIT name the dosing period the parameter belongs to, as PP gives them.
  • AVAL is the parameter's numeric result in standard units.
  • PRECONC is the concentration of the period's pre-dose sample: the PC record planned at PREDOSE whose reference dose time is the parameter's. A result below the lower limit of quantitation counts as 0. Empty when the period has no pre-dose sample, or the sample was not done; no other sample stands in for it.
  • PREPCMAX is PRECONC as a percentage of the same subject's maximum concentration (Cmax) in the same period, not rounded; empty when PRECONC is.
  • ANL01FL is empty on every parameter of a period whose PREPCMAX is greater than 5, and Y on every other record, including a period whose PREPCMAX is empty. Exactly 5 percent stays in.

Note: every period is checked, the first one included, and the period is the unit left out: the subject's other period keeps Y, and every record stays in the dataset. The pre-dose result, the percentage and the flag repeat on every parameter of the period.

Inputs

Under review
2 source files

input/pc.csv

Edit
15 rows
input/pc.csv
STUDYIDDOMAINUSUBJIDPCSEQPCTESTCDPCTESTPCORRESPCORRESUPCSTRESCPCSTRESNPCSTRESUPCSTATPCLLOQVISITNUMVISITPCDTCPCTPTPCTPTNUMPCRFTDTC
YAMAA-01PC1DRUGXDrug X<0.5ng/mL<0.5—ng/mL—0.51PERIOD 12025-03-03T07:45PREDOSE02025-03-03T08:00
YAMAA-01PC2DRUGXDrug X1ng/mL11ng/mL—0.52PERIOD 22025-03-10T07:45PREDOSE02025-03-10T08:00
YAMAA-01PC3DRUGXDrug X60ng/mL6060ng/mL—0.52PERIOD 22025-03-10T09:001H12025-03-10T08:00
YAMAA-01PC1DRUGXDrug X<0.5ng/mL<0.5—ng/mL—0.51PERIOD 12025-03-03T07:45PREDOSE02025-03-03T08:00
YAMAA-01PC2DRUGXDrug X7ng/mL77ng/mL—0.52PERIOD 22025-03-10T07:45PREDOSE02025-03-10T08:00
YAMAA-01PC1DRUGXDrug X<0.5ng/mL<0.5—ng/mL—0.51PERIOD 12025-03-03T07:45PREDOSE02025-03-03T08:00
YAMAA-01PC2DRUGXDrug X3ng/mL33ng/mL—0.52PERIOD 22025-03-10T07:45PREDOSE02025-03-10T08:00
YAMAA-01PC1DRUGXDrug X<0.5ng/mL<0.5—ng/mL—0.51PERIOD 12025-03-03T07:45PREDOSE02025-03-03T08:00
YAMAA-01PC2DRUGXDrug X2ng/mL22ng/mL—0.52PERIOD 22025-03-10T07:45PREDOSE02025-03-10T08:00
YAMAA-01PC1DRUGXDrug X6ng/mL66ng/mL—0.51PERIOD 12025-03-03T07:45PREDOSE02025-03-03T08:00
YAMAA-01PC2DRUGXDrug X<0.5ng/mL<0.5—ng/mL—0.52PERIOD 22025-03-10T07:45PREDOSE02025-03-10T08:00
YAMAA-01PC1DRUGXDrug X<0.5ng/mL<0.5—ng/mL—0.51PERIOD 12025-03-03T07:45PREDOSE02025-03-03T08:00
YAMAA-01PC2DRUGXDrug X—ng/mL——ng/mLNOT DONE0.52PERIOD 22025-03-10T07:45PREDOSE02025-03-10T08:00
YAMAA-01PC1DRUGXDrug X<0.5ng/mL<0.5—ng/mL—0.51PERIOD 12025-03-03T07:45PREDOSE02025-03-03T08:00
YAMAA-01PC2DRUGXDrug X40ng/mL4040ng/mL—0.52PERIOD 22025-03-10T09:001H12025-03-10T08:00

input/pp.csv

Edit
20 rows
input/pp.csv
STUDYIDDOMAINUSUBJIDPPSEQPPTESTCDPPTESTPPCATPPSTRESNPPSTRESUPPSPECVISITNUMVISITPPRFTDTC
YAMAA-01PP1CMAXMax ConcDRUGX100ng/mLPLASMA1PERIOD 12025-03-03T08:00
YAMAA-01PP2AUCLSTAUC to Last Nonzero ConcDRUGX800h*ng/mLPLASMA1PERIOD 12025-03-03T08:00
YAMAA-01PP3CMAXMax ConcDRUGX80ng/mLPLASMA2PERIOD 22025-03-10T08:00
YAMAA-01PP4AUCLSTAUC to Last Nonzero ConcDRUGX640h*ng/mLPLASMA2PERIOD 22025-03-10T08:00
YAMAA-01PP5TMAXTime of CMAXDRUGX2hPLASMA2PERIOD 22025-03-10T08:00
YAMAA-01PP1CMAXMax ConcDRUGX160ng/mLPLASMA1PERIOD 12025-03-03T08:00
YAMAA-01PP2CMAXMax ConcDRUGX100ng/mLPLASMA2PERIOD 22025-03-10T08:00
YAMAA-01PP3AUCLSTAUC to Last Nonzero ConcDRUGX900h*ng/mLPLASMA2PERIOD 22025-03-10T08:00
YAMAA-01PP1CMAXMax ConcDRUGX70ng/mLPLASMA1PERIOD 12025-03-03T08:00
YAMAA-01PP2CMAXMax ConcDRUGX60ng/mLPLASMA2PERIOD 22025-03-10T08:00
YAMAA-01PP1CMAXMax ConcDRUGX32ng/mLPLASMA1PERIOD 12025-03-03T08:00
YAMAA-01PP2CMAXMax ConcDRUGX80ng/mLPLASMA2PERIOD 22025-03-10T08:00
YAMAA-01PP1CMAXMax ConcDRUGX75ng/mLPLASMA1PERIOD 12025-03-03T08:00
YAMAA-01PP2AUCLSTAUC to Last Nonzero ConcDRUGX600h*ng/mLPLASMA1PERIOD 12025-03-03T08:00
YAMAA-01PP3CMAXMax ConcDRUGX90ng/mLPLASMA2PERIOD 22025-03-10T08:00
YAMAA-01PP1CMAXMax ConcDRUGX6ng/mLPLASMA1PERIOD 12025-03-03T08:00
YAMAA-01PP2CMAXMax ConcDRUGX85ng/mLPLASMA2PERIOD 22025-03-10T08:00
YAMAA-01PP1CMAXMax ConcDRUGX95ng/mLPLASMA1PERIOD 12025-03-03T08:00
YAMAA-01PP2CMAXMax ConcDRUGX90ng/mLPLASMA2PERIOD 22025-03-10T08:00
YAMAA-01PP3AUCLSTAUC to Last Nonzero ConcDRUGX700h*ng/mLPLASMA2PERIOD 22025-03-10T08:00

Expected output

Under review
20 expected rows

expected/adpp.csv

Edit
20 rows
expected/adpp.csv
STUDYIDUSUBJIDVISITNUMVISITPARAMCDPARAMAVALPRECONCPREPCMAXANL01FL
YAMAA-011PERIOD 1CMAXMax Conc10000Y
YAMAA-011PERIOD 1AUCLSTAUC to Last Nonzero Conc80000Y
YAMAA-012PERIOD 2CMAXMax Conc8011.25Y
YAMAA-012PERIOD 2AUCLSTAUC to Last Nonzero Conc64011.25Y
YAMAA-012PERIOD 2TMAXTime of CMAX211.25Y
YAMAA-011PERIOD 1CMAXMax Conc16000Y
YAMAA-012PERIOD 2CMAXMax Conc10077—
YAMAA-012PERIOD 2AUCLSTAUC to Last Nonzero Conc90077—
YAMAA-011PERIOD 1CMAXMax Conc7000Y
YAMAA-012PERIOD 2CMAXMax Conc6035Y
YAMAA-011PERIOD 1CMAXMax Conc3200Y
YAMAA-012PERIOD 2CMAXMax Conc8022.5Y
YAMAA-011PERIOD 1CMAXMax Conc7568—
YAMAA-011PERIOD 1AUCLSTAUC to Last Nonzero Conc60068—
YAMAA-012PERIOD 2CMAXMax Conc9000Y
YAMAA-011PERIOD 1CMAXMax Conc600Y
YAMAA-012PERIOD 2CMAXMax Conc85——Y
YAMAA-011PERIOD 1CMAXMax Conc9500Y
YAMAA-012PERIOD 2CMAXMax Conc90——Y
YAMAA-012PERIOD 2AUCLSTAUC to Last Nonzero Conc700——Y
Shaded columns are derived— = missing value

Human review and assessment

Your review

3 questions and your comments · View benchmark discussions

Mapping spec

Generated from the benchmark YAML; do not edit by hand

Dataset NameVariable NameVariable LabelTypeCodelist/Controlled TermsCoreComputational MethodOrigin
ADPPSTUDYIDStudy IdentifiercharacterCopy value from PP.STUDYID.Predecessor
ADPPUSUBJIDUnique Subject IdentifiercharacterCopy value from PP.USUBJID.Predecessor
ADPPVISITNUMVisit NumbernumericCopy value from PP.VISITNUM.Predecessor
ADPPVISITVisit NamecharacterCopy value from PP.VISIT.Predecessor
ADPPPARAMCDParameter CodecharacterCopy value from PP.PPTESTCD.Predecessor
ADPPPARAMParametercharacterCopy value from PP.PPTEST.Predecessor
ADPPAVALAnalysis ValuenumericCopy value from PP.PPSTRESN.Predecessor
ADPPPRECONCPre-Dose Concentration of the PeriodnumericAggregate ONLY(PREVAL) over records whose STUDYID equals PP.STUDYID, USUBJID equals PP.USUBJID and PCRFTDTC equals PP.PPRFTDTC, where PC.PCTPT = 'PREDOSE', with PREVAL as if PC.PCSTRESC LIKE '<%' then "0"; otherwise "PC.PCSTRESN".Derived
ADPPPREPCMAXPre-Dose Concentration as Percent of CmaxnumericCompute 100 * PRECONC / NULLIF(CMAXPER, 0).Derived
ADPPANL01FLAnalysis Flag 01characterY"Y" when PREPCMAX IS NULL OR PREPCMAX <= 5; blank otherwise.Derived
VariablePermitted values
ANL01FLY
VersionDateAuthorDescriptionReviewerSign-off
1.72026-10-20yamaa docs buildRead 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.62026-10-17yamaa docs buildDescribe collected date parts written as ISO 8601 date text and times of day counted in seconds since midnight
1.52026-10-17yamaa docs buildName 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.42026-10-15yamaa docs buildState datetime precision codes through the hour and minute, and complete only the time parts a collected datetime lacks
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

Agent prompt

The request an agent receives with the input files; each tier states no more than the one above

prompts/adam-adpp-carryover-exclusion/full.md

Edit
35 lines

Following CDISC ADaM standards, use the provided PC and PP datasets to create an ADPP dataset with one record per subject, period, and pharmacokinetic parameter.

The output dataset should contain the following columns in this order: STUDYID, USUBJID, VISITNUM, VISIT, PARAMCD, PARAM, AVAL, PRECONC, PREPCMAX, ANL01FL

  • VISITNUM and VISIT name the dosing period the parameter belongs to, as PP gives them, and PARAMCD and PARAM are the parameter's test code and test name.
  • AVAL is the parameter's numeric result in standard units.
  • PRECONC is the concentration of the period's pre-dose sample: the PC record for the same subject planned at "PREDOSE" whose reference dose time is the parameter's.
  • A pre-dose result below the lower limit of quantitation, recorded as a character result beginning with "<", counts as 0.
  • PRECONC has no value when the period has no pre-dose sample or the sample was not done, and no other sample stands in for it.
  • PREPCMAX is PRECONC as a percentage of the same subject's Cmax in the same period, the AVAL of the period's "CMAX" parameter, and is not rounded.
  • PREPCMAX has no value when PRECONC has no value, and has no value when the period's Cmax is zero.
  • ANL01FL has no value on every parameter of a period whose PREPCMAX is greater than 5, and is "Y" on every other record, including a period whose PREPCMAX has no value.
  • Exactly 5 percent stays in.
  • Every period is checked, the first one included, and the period is the unit left out: the subject's other period keeps "Y" and every record stays in the dataset.
  • PRECONC, PREPCMAX and ANL01FL repeat on every parameter of the period.

Read the source datasets from /app/input and save the completed dataset as /app/output/adpp.csv.

prompts/adam-adpp-carryover-exclusion/conventions.md

Edit
12 lines

Following CDISC ADaM standards, use the provided PC and PP datasets to create an ADPP dataset with one record per subject, period, and pharmacokinetic parameter.

The output dataset should contain the following columns in this order: STUDYID, USUBJID, VISITNUM, VISIT, PARAMCD, PARAM, AVAL, PRECONC, PREPCMAX, ANL01FL

PREPCMAX is not rounded. ANL01FL is "Y" or has no value.

Read the source datasets from /app/input and save the completed dataset as /app/output/adpp.csv.

prompts/adam-adpp-carryover-exclusion/brief.md

Edit
10 lines

Following CDISC ADaM standards, use the provided PC and PP datasets to create an ADPP dataset with one record per subject, period, and pharmacokinetic parameter.

The output dataset should contain the following columns in this order: STUDYID, USUBJID, VISITNUM, VISIT, PARAMCD, PARAM, AVAL, PRECONC, PREPCMAX, ANL01FL

Read the source datasets from /app/input and save the completed dataset as /app/output/adpp.csv.

yamaa code

Public calls generated from benchmark.yaml; results must match the expected output

R

Edit
3 lines
library(yamaa)yamaa_spec("spec.yaml")$run()$output

Python

Edit
3 lines
import yamaayamaa.spec("spec.yaml").run().output

Solution without yamaa

Written from the full prompt and the inputs alone; CI checks it reproduces the expected output

solutions/adam-adpp-carryover-exclusion/result.R

Edit
60 lines
# Reference solution for the yamaa benchmark adam-adpp-carryover-exclusion (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(stringr)pp <- read_csv(  "/app/input/pp.csv",  col_types = cols(    PPSTRESN = col_double(),    VISITNUM = col_integer(),    .default = col_character()  ))pc <- read_csv(  "/app/input/pc.csv",  col_types = cols(PCSTRESN = col_double(), .default = col_character()))# The period's pre-dose sample: planned at PREDOSE, with the parameter's# reference dose time. A below-limit result ("<" and the limit) counts as 0;# a sample not done has no result and gives no value.predose <- pc |>  filter(PCTPT == "PREDOSE") |>  transmute(    STUDYID, USUBJID,    PPRFTDTC = PCRFTDTC,    PRECONC = if_else(      !is.na(PCSTRESC) & str_starts(PCSTRESC, fixed("<")), 0, PCSTRESN    )  )stopifnot(!anyDuplicated(predose[c("STUDYID", "USUBJID", "PPRFTDTC")]))# The same subject's Cmax in the same period.cmax <- pp |>  filter(PPTESTCD == "CMAX") |>  transmute(STUDYID, USUBJID, PPRFTDTC, CMAX = PPSTRESN)stopifnot(!anyDuplicated(cmax[c("STUDYID", "USUBJID", "PPRFTDTC")]))keys <- c("STUDYID", "USUBJID", "PPRFTDTC")adpp <- pp |>  left_join(predose, by = keys) |>  left_join(cmax, by = keys) |>  mutate(    PREPCMAX = if_else(!is.na(CMAX) & CMAX != 0, 100 * PRECONC / CMAX, NA_real_),    # Left out only when the percentage is known and above 5.    ANL01FL = if_else(!is.na(PREPCMAX) & PREPCMAX > 5, NA_character_, "Y")  ) |>  transmute(    STUDYID, USUBJID, VISITNUM, VISIT,    PARAMCD = PPTESTCD, PARAM = PPTEST, AVAL = PPSTRESN,    PRECONC, PREPCMAX, ANL01FL  )dir.create("/app/output", showWarnings = FALSE)write_csv(adpp, "/app/output/adpp.csv", na = "")

solutions/adam-adpp-carryover-exclusion/result.py

Edit
119 lines
# Reference solution for the yamaa benchmark adam-adpp-carryover-exclusion (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."""Create ADPP from PC and PP: pre-dose carryover exclusion flag.One record per subject, period, and pharmacokinetic parameter (from PP).PRECONC is the concentration of the period's pre-dose PC sample (planned"PREDOSE", matched to the parameter by reference dose time); a characterresult beginning with "<" counts as 0. PREPCMAX is PRECONC as apercentage of the period's Cmax. ANL01FL is blank on every parameter ofa period whose PREPCMAX is greater than 5, and "Y" otherwise."""import csvimport osINPUT_DIR = "/app/input"OUTPUT_DIR = "/app/output"def read_csv(name):    with open(os.path.join(INPUT_DIR, name), newline="") as f:        return list(csv.DictReader(f))def fmt(value):    """Format a float for CSV: integers without a decimal point."""    if value is None:        return ""    if value == int(value):        return str(int(value))    return repr(value)def main():    pc = read_csv("pc.csv")    pp = read_csv("pp.csv")    # Pre-dose concentrations keyed by (subject, reference dose time).    preconc = {}    for row in pc:        if row["PCTPT"] != "PREDOSE":            continue        key = (row["USUBJID"], row["PCRFTDTC"])        if row["PCSTAT"] == "NOT DONE":            preconc[key] = None        elif row["PCSTRESC"].startswith("<"):            preconc[key] = 0.0        elif row["PCSTRESN"]:            preconc[key] = float(row["PCSTRESN"])        else:            preconc[key] = None    # Cmax (AVAL of the period's CMAX parameter) per (subject, visit).    cmax = {}    for row in pp:        if row["PPTESTCD"] == "CMAX":            cmax[(row["USUBJID"], row["VISITNUM"])] = float(row["PPSTRESN"])    # Period-level values: PRECONC, PREPCMAX, ANL01FL per (subject, visit).    period = {}    for row in pp:        key = (row["USUBJID"], row["VISITNUM"])        if key in period:            continue        pre = preconc.get((row["USUBJID"], row["PPRFTDTC"]))        c = cmax.get(key)        if pre is None or c is None or c == 0:            prepct = None        else:            prepct = 100.0 * pre / c        if prepct is not None and prepct > 5:            anl01fl = ""        else:            anl01fl = "Y"        period[key] = (pre, prepct, anl01fl)    out_rows = []    for row in pp:        pre, prepct, anl01fl = period[(row["USUBJID"], row["VISITNUM"])]        out_rows.append(            {                "STUDYID": row["STUDYID"],                "USUBJID": row["USUBJID"],                "VISITNUM": row["VISITNUM"],                "VISIT": row["VISIT"],                "PARAMCD": row["PPTESTCD"],                "PARAM": row["PPTEST"],                "AVAL": fmt(float(row["PPSTRESN"])),                "PRECONC": fmt(pre),                "PREPCMAX": fmt(prepct),                "ANL01FL": anl01fl,            }        )    fieldnames = [        "STUDYID",        "USUBJID",        "VISITNUM",        "VISIT",        "PARAMCD",        "PARAM",        "AVAL",        "PRECONC",        "PREPCMAX",        "ANL01FL",    ]    os.makedirs(OUTPUT_DIR, exist_ok=True)    with open(os.path.join(OUTPUT_DIR, "adpp.csv"), "w", newline="") as f:        writer = csv.DictWriter(f, fieldnames=fieldnames)        writer.writeheader()        writer.writerows(out_rows)if __name__ == "__main__":    main()

solutions/adam-adpp-carryover-exclusion/result.sas

Edit
81 lines
/* opensas reference solution for the yamaa benchmark adam-adpp-carryover-exclusion.   Reads the benchmark inputs and derives the requested output.   Execute with the existing opensas runtime: opensas /app/output/result.sas. */data pp;  length STUDYID DOMAIN USUBJID PPTESTCD PPTEST PPCAT PPSTRESU PPSPEC VISIT PPRFTDTC $200;  infile "/app/input/pp.csv" dsd dlm="," firstobs=2 truncover lrecl=32767;  input STUDYID : $char200. DOMAIN : $char200. USUBJID : $char200. PPSEQ        PPTESTCD : $char200. PPTEST : $char200. PPCAT : $char200. PPSTRESN        PPSTRESU : $char200. PPSPEC : $char200. VISITNUM VISIT : $char200.        PPRFTDTC : $char200.;  ORD = _n_;run;data pc;  length STUDYID DOMAIN USUBJID PCTESTCD PCTEST PCORRES PCORRESU PCSTRESC PCSTRESU         PCSTAT VISIT PCDTC PCTPT PCRFTDTC $200;  infile "/app/input/pc.csv" dsd dlm="," firstobs=2 truncover lrecl=32767;  input STUDYID : $char200. DOMAIN : $char200. USUBJID : $char200. PCSEQ        PCTESTCD : $char200. PCTEST : $char200. PCORRES : $char200.        PCORRESU : $char200. PCSTRESC : $char200. PCSTRESN PCSTRESU : $char200.        PCSTAT : $char200. PCLLOQ VISITNUM VISIT : $char200. PCDTC : $char200.        PCTPT : $char200. PCTPTNUM PCRFTDTC : $char200.;run;/* The period's pre-dose sample: planned at PREDOSE, with the parameter's   reference dose time. A below-limit result counts as 0; a sample not done   has no result and gives no value. */data predose;  length PRFT $200;  set pc;  if PCTPT = 'PREDOSE';  PRFT = PCRFTDTC;  if index(PCSTRESC, '<') = 1 then PRECONC = 0;  else PRECONC = PCSTRESN;  keep STUDYID USUBJID PRFT PRECONC;run;/* The same subject's Cmax in the same period. */data cmax;  length CRFT $200;  set pp;  if PPTESTCD = 'CMAX';  CRFT = PPRFTDTC;  CMAXV = PPSTRESN;  keep STUDYID USUBJID CRFT CMAXV;run;proc sql;  create table withpre as    select p.*, d.PRECONC    from pp as p left join predose as d      on p.STUDYID = d.STUDYID and p.USUBJID = d.USUBJID and p.PPRFTDTC = d.PRFT;  create table withcmax as    select p.*, c.CMAXV    from withpre as p left join cmax as c      on p.STUDYID = c.STUDYID and p.USUBJID = c.USUBJID and p.PPRFTDTC = c.CRFT;quit;/* Left out only when the percentage is known and above 5. */data final;  length PARAMCD PARAM $200 ANL01FL $1;  set withcmax;  PARAMCD = PPTESTCD;  PARAM = PPTEST;  AVAL = PPSTRESN;  if not missing(PRECONC) and not missing(CMAXV) and CMAXV ne 0 then    PREPCMAX = 100 * PRECONC / CMAXV;  ANL01FL = 'Y';  if not missing(PREPCMAX) and PREPCMAX > 5 then ANL01FL = ' ';run;proc sort data=final; by ORD; run;proc sql;  create table adpp as    select STUDYID, USUBJID, VISITNUM, VISIT, PARAMCD, PARAM, AVAL, PRECONC,           PREPCMAX, ANL01FL    from final;quit;proc export data=adpp outfile="/app/output/adpp.csv" dbms=csv replace; run;