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: build one Subject Elements (SE) record per subject per element
the subject entered, carrying SESEQ, ETCD, ELEMENT, TAETORD,
EPOCH, SESTDTC, SEENDTC, SESTDY, SEENDY, and SEUPDES.
Input: two sources:
dm.csv: subject-level demographics (one row per subject) with the planned arm code and the reference dates (informed consent, reference start, end of study participation).odm.csv: a long-format Operational Data Model (ODM) extract, one row per subject per study event per item, carrying each element's trial-design attributes (description, planned order, epoch) asIT.TE.*/IT.TA.*items and the first and last dosing dates asIT.EX.*items.
The extract repeats each subject's trial-design attributes and dosing
dates on every study event, so each SE record derives from its own event
context without reading across events. The reference dates come from
dm.csv, matched on the subject keys the two datasets share (STUDYID,
USUBJID).
Variables:
SESEQnumbers the subject's elements in planned order, so it equalsTAETORD.ETCDis the element code, taken from the subject's study event.ELEMENTis the element description, e.g. Screening.TAETORDis the planned order of the element within the subject's arm.EPOCHis the epoch the element belongs to, e.g. TREATMENT.SESTDTCis the date the subject actually started the element: informed consent for screening, first dosing date for treatment, last dosing date for follow-up (and for any other or missing epoch).SEENDTCis the date the subject actually ended the element: first dosing date for screening, last dosing date for treatment, end of study participation for follow-up (and for any other or missing epoch).SESTDYis the study day of the element start, counting the reference start date as day 1 with no day 0; blank when either date is missing.SEENDYis the study day of the element end, counted the same way.SEUPDESis always blank: the records are built only from planned elements, and the column describes only an unplanned one.
Note: elements are recorded back to back: an element ends on the day the next one starts. The treatment element ends on the actual last dosing date, so a subject who stopped dosing early has a shorter treatment element and an earlier follow-up start than the plan described.
Provenance: the trial design, subjects, dates, and dosing dates are invented fixtures.
Inputs
Under review2 source filesinput/dm.csv
Edit2 rows| STUDYID | USUBJID | ARMCD | RFICDTC | RFSTDTC | RFPENDTC |
|---|---|---|---|---|---|
| YAMAA-01 | A | 2026-01-02 | 2026-01-05 | 2026-02-17 | |
| YAMAA-01 | B | 2026-01-03 | 2026-01-05 | 2026-02-17 |
input/odm.csv
Edit30 rows| StudyOID | MetaDataVersionOID | SubjectKey | StudyEventOID | StudyEventRepeatKey | ItemGroupOID | ItemGroupRepeatKey | ItemOID | Value |
|---|---|---|---|---|---|---|---|---|
| YAMAA-01 | MDV.1 | 001 | SCRN | 1 | IG.TE | 1 | IT.TE.ELEMENT | Screening |
| YAMAA-01 | MDV.1 | 001 | SCRN | 1 | IG.TE | 1 | IT.TA.TAETORD | 1 |
| YAMAA-01 | MDV.1 | 001 | SCRN | 1 | IG.TE | 1 | IT.TA.EPOCH | SCREENING |
| YAMAA-01 | MDV.1 | 001 | SCRN | 1 | IG.EX | 1 | IT.EX.FIRSTDTC | 2026-01-06 |
| YAMAA-01 | MDV.1 | 001 | SCRN | 1 | IG.EX | 1 | IT.EX.LASTDTC | 2026-02-02 |
| YAMAA-01 | MDV.1 | 001 | TRTA | 1 | IG.TE | 1 | IT.TE.ELEMENT | Treatment A |
| YAMAA-01 | MDV.1 | 001 | TRTA | 1 | IG.TE | 1 | IT.TA.TAETORD | 2 |
| YAMAA-01 | MDV.1 | 001 | TRTA | 1 | IG.TE | 1 | IT.TA.EPOCH | TREATMENT |
| YAMAA-01 | MDV.1 | 001 | TRTA | 1 | IG.EX | 1 | IT.EX.FIRSTDTC | 2026-01-06 |
| YAMAA-01 | MDV.1 | 001 | TRTA | 1 | IG.EX | 1 | IT.EX.LASTDTC | 2026-02-02 |
| YAMAA-01 | MDV.1 | 001 | FUP | 1 | IG.TE | 1 | IT.TE.ELEMENT | Follow-up |
| YAMAA-01 | MDV.1 | 001 | FUP | 1 | IG.TE | 1 | IT.TA.TAETORD | 3 |
| YAMAA-01 | MDV.1 | 001 | FUP | 1 | IG.TE | 1 | IT.TA.EPOCH | FOLLOW-UP |
| YAMAA-01 | MDV.1 | 001 | FUP | 1 | IG.EX | 1 | IT.EX.FIRSTDTC | 2026-01-06 |
| YAMAA-01 | MDV.1 | 001 | FUP | 1 | IG.EX | 1 | IT.EX.LASTDTC | 2026-02-02 |
| YAMAA-01 | MDV.1 | 002 | SCRN | 1 | IG.TE | 1 | IT.TE.ELEMENT | Screening |
| YAMAA-01 | MDV.1 | 002 | SCRN | 1 | IG.TE | 1 | IT.TA.TAETORD | 1 |
| YAMAA-01 | MDV.1 | 002 | SCRN | 1 | IG.TE | 1 | IT.TA.EPOCH | SCREENING |
| YAMAA-01 | MDV.1 | 002 | SCRN | 1 | IG.EX | 1 | IT.EX.FIRSTDTC | 2026-01-06 |
| YAMAA-01 | MDV.1 | 002 | SCRN | 1 | IG.EX | 1 | IT.EX.LASTDTC | 2026-01-20 |
| YAMAA-01 | MDV.1 | 002 | TRTB | 1 | IG.TE | 1 | IT.TE.ELEMENT | Treatment B |
| YAMAA-01 | MDV.1 | 002 | TRTB | 1 | IG.TE | 1 | IT.TA.TAETORD | 2 |
| YAMAA-01 | MDV.1 | 002 | TRTB | 1 | IG.TE | 1 | IT.TA.EPOCH | TREATMENT |
| YAMAA-01 | MDV.1 | 002 | TRTB | 1 | IG.EX | 1 | IT.EX.FIRSTDTC | 2026-01-06 |
| YAMAA-01 | MDV.1 | 002 | TRTB | 1 | IG.EX | 1 | IT.EX.LASTDTC | 2026-01-20 |
| YAMAA-01 | MDV.1 | 002 | FUP | 1 | IG.TE | 1 | IT.TE.ELEMENT | Follow-up |
| YAMAA-01 | MDV.1 | 002 | FUP | 1 | IG.TE | 1 | IT.TA.TAETORD | 3 |
| YAMAA-01 | MDV.1 | 002 | FUP | 1 | IG.TE | 1 | IT.TA.EPOCH | FOLLOW-UP |
| YAMAA-01 | MDV.1 | 002 | FUP | 1 | IG.EX | 1 | IT.EX.FIRSTDTC | 2026-01-06 |
| YAMAA-01 | MDV.1 | 002 | FUP | 1 | IG.EX | 1 | IT.EX.LASTDTC | 2026-01-20 |
Expected output
Under review6 expected rowsexpected/se.csv
Edit6 rows| DOMAIN | STUDYID | USUBJID | SESEQ | ETCD | ELEMENT | TAETORD | EPOCH | SESTDTC | SEENDTC | SESTDY | SEENDY | SEUPDES |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| SE | YAMAA-01 | 1 | SCRN | Screening | 1 | SCREENING | 2026-01-02 | 2026-01-06 | -3 | 2 | — | |
| SE | YAMAA-01 | 2 | TRTA | Treatment A | 2 | TREATMENT | 2026-01-06 | 2026-02-02 | 2 | 29 | — | |
| SE | YAMAA-01 | 3 | FUP | Follow-up | 3 | FOLLOW-UP | 2026-02-02 | 2026-02-17 | 29 | 44 | — | |
| SE | YAMAA-01 | 1 | SCRN | Screening | 1 | SCREENING | 2026-01-03 | 2026-01-06 | -2 | 2 | — | |
| SE | YAMAA-01 | 2 | TRTB | Treatment B | 2 | TREATMENT | 2026-01-06 | 2026-01-20 | 2 | 16 | — | |
| SE | YAMAA-01 | 3 | FUP | Follow-up | 3 | FOLLOW-UP | 2026-01-20 | 2026-02-17 | 16 | 44 | — |
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 "SE". | 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 | ||||
| ETCD | Element Code | Char | Collected | Copy value from ODM.StudyEventOID. | SDTM | 4 | ||||
| ELEMENT | Description of Element | Char | Collected | Copy value from ODM.Value where ODM.ItemOID = 'IT.TE.ELEMENT'. | SDTM | 5 | ||||
| TAETORD | Planned Order of Element within Arm | Num | Collected | Copy value from ODM.Value where ODM.ItemOID = 'IT.TA.TAETORD'. | SDTM | 6 | ||||
| SESEQ | Sequence Number | Num | Derived | Copy value from TAETORD. | SDTM | 7 | ||||
| EPOCH | Epoch | Char | Collected | Copy value from ODM.Value where ODM.ItemOID = 'IT.TA.EPOCH'. | SDTM | 8 | ||||
| SESTDTC | Start Date/Time of Element | Char | ISO 8601 | Derived | If EPOCH = 'SCREENING' then "DM.RFICDTC"; If EPOCH = 'TREATMENT' then "FIRSTDTC"; otherwise "LASTDTC". | SDTM | 9 | |||
| SEENDTC | End Date/Time of Element | Char | ISO 8601 | Derived | If EPOCH = 'SCREENING' then "FIRSTDTC"; If EPOCH = 'TREATMENT' then "LASTDTC"; otherwise "DM.RFPENDTC". | SDTM | 10 | |||
| SESTDY | Study Day of Start of Element | Num | Derived | CDISC study day of SESTDTC against DM.RFSTDTC as day 1; there is no day zero. | SDTM | 11 | ||||
| SEENDY | Study Day of End of Element | Num | Derived | CDISC study day of SEENDTC against DM.RFSTDTC as day 1; there is no day zero. | SDTM | 12 | ||||
| SEUPDES | Description of Unplanned Element | Char | Assigned | Set constant value "None". | SDTM | 13 |
| 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-se-subject-elements/full.md
Edit31 linesFollowing CDISC SDTM standards, use the provided DM and ODM datasets to create an SE dataset with one record per subject per element the subject entered.
The output dataset should contain the following columns in this order: DOMAIN, STUDYID, USUBJID, SESEQ, ETCD, ELEMENT, TAETORD, EPOCH, SESTDTC, SEENDTC, SESTDY, SEENDY, SEUPDES
DOMAIN is "SE". STUDYID is the study OID as given in ODM and USUBJID is the subject key as given in ODM. ETCD is the code of the study event the record is built from. ELEMENT is the element description the extract gives for that event (the IT.TE.ELEMENT item). TAETORD is the planned order of the element within the subject's arm (the IT.TA.TAETORD item). EPOCH is the epoch the extract gives for that event (the IT.TA.EPOCH item). SESEQ numbers the subject's elements in planned order and equals TAETORD. The extract gives each subject a first dosing date and a last dosing date, the same on every study event of the subject. SESTDTC is the subject's informed consent date in DM when EPOCH is "SCREENING", the subject's first dosing date when EPOCH is "TREATMENT", and the subject's last dosing date for any other epoch or when EPOCH has no value. SEENDTC is the subject's first dosing date when EPOCH is "SCREENING", the subject's last dosing date when EPOCH is "TREATMENT", and the subject's end of study participation date in DM for any other epoch or when EPOCH has no value. SESTDY is the study day of SESTDTC counted from the subject's reference start date in DM, and has no value when either date has no value. SEENDY is the study day of SEENDTC counted the same way, and has no value when either date has no value. SEUPDES has no value on every record.
Read the source datasets from /app/input and save the completed dataset as /app/output/se.csv.
prompts/sdtm-se-subject-elements/conventions.md
Edit14 linesFollowing CDISC SDTM standards, use the provided DM and ODM datasets to create an SE dataset with one record per subject per element the subject entered.
The output dataset should contain the following columns in this order: DOMAIN, STUDYID, USUBJID, SESEQ, ETCD, ELEMENT, TAETORD, EPOCH, SESTDTC, SEENDTC, SESTDY, SEENDY, SEUPDES
DOMAIN is "SE". SESTDY is the study day of SESTDTC counted from the subject's reference start date in DM, and SEENDY is the study day of SEENDTC counted the same way. SEUPDES has no value on every record.
Read the source datasets from /app/input and save the completed dataset as /app/output/se.csv.
prompts/sdtm-se-subject-elements/brief.md
Edit10 linesFollowing CDISC SDTM standards, use the provided DM and ODM datasets to create an SE dataset with one record per subject per element the subject entered.
The output dataset should contain the following columns in this order: DOMAIN, STUDYID, USUBJID, SESEQ, ETCD, ELEMENT, TAETORD, EPOCH, SESTDTC, SEENDTC, SESTDY, SEENDY, SEUPDES
Read the source datasets from /app/input and save the completed dataset as /app/output/se.csv.
R
Edit3 lineslibrary(yamaa)yamaa_spec("spec.yaml")$run()$outputPython
Edit3 linesimport yamaayamaa.spec("spec.yaml").run().outputsolutions/sdtm-se-subject-elements/result.R
Edit74 lines# Reference solution for the yamaa benchmark sdtm-se-subject-elements (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)dm <- read_csv( "/app/input/dm.csv", col_types = cols(.default = col_character()))odm <- read_csv( "/app/input/odm.csv", col_types = cols(.default = col_character()))wide <- odm |> mutate(Value = na_if(Value, "")) |> pivot_wider( id_cols = c(SubjectKey, StudyEventOID), names_from = ItemOID, values_from = Value, values_fn = function(x) x[[1]] )study_day <- function(ref, day) { ifelse( is.na(ref) | ref == "" | is.na(day) | day == "", NA_character_, { delta <- as.integer(as.Date(day) - as.Date(ref)) as.character(ifelse(delta >= 0, delta + 1L, delta)) } )}se <- wide |> left_join(dm, by = c("SubjectKey" = "USUBJID")) |> mutate( DOMAIN = "SE", STUDYID = STUDYID, USUBJID = SubjectKey, SESEQ = IT.TA.TAETORD, ETCD = StudyEventOID, ELEMENT = IT.TE.ELEMENT, TAETORD = IT.TA.TAETORD, EPOCH = IT.TA.EPOCH, first_dtc = IT.EX.FIRSTDTC, last_dtc = IT.EX.LASTDTC, SESTDTC = case_when( EPOCH == "SCREENING" ~ RFICDTC, EPOCH == "TREATMENT" ~ first_dtc, TRUE ~ last_dtc ), SEENDTC = case_when( EPOCH == "SCREENING" ~ first_dtc, EPOCH == "TREATMENT" ~ last_dtc, TRUE ~ RFPENDTC ), SESTDY = study_day(RFSTDTC, SESTDTC), SEENDY = study_day(RFSTDTC, SEENDTC), SEUPDES = NA_character_ ) |> arrange(USUBJID, suppressWarnings(as.integer(TAETORD))) |> select( DOMAIN, STUDYID, USUBJID, SESEQ, ETCD, ELEMENT, TAETORD, EPOCH, SESTDTC, SEENDTC, SESTDY, SEENDY, SEUPDES )dir.create("/app/output", showWarnings = FALSE)write_csv(se, "/app/output/se.csv", na = "")solutions/sdtm-se-subject-elements/result.py
Edit154 lines# Reference solution for the yamaa benchmark sdtm-se-subject-elements (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."""Build the SDTM SE (Subject Elements) dataset from DM and ODM extracts.One record per subject per element the subject entered. Dates and studydays follow the epoch-based rules described in the task."""import csvfrom datetime import dateINPUT_DIR = "/app/input"OUTPUT_DIR = "/app/output"def parse_date(value): """Parse an ISO date (or the date part of an ISO datetime). Returns a datetime.date, or None when there is no usable value. """ if value is None: return None text = str(value).strip() if not text: return None try: return date.fromisoformat(text[:10]) except ValueError: return Nonedef study_day(target, reference): """SDTM study day of target counted from the reference start date. No value when either date has no value. There is no day zero: the reference date itself is day 1 and the day before it is day -1. """ if target is None or reference is None: return "" diff = (target - reference).days return diff + 1 if diff >= 0 else diffdef main(): # DM: one row per subject with the dates the SE rules draw on. dm = {} with open(f"{INPUT_DIR}/dm.csv", newline="", encoding="utf-8") as handle: for row in csv.DictReader(handle): dm[row["USUBJID"]] = { "rficdtc": (row.get("RFICDTC") or "").strip(), "rfstdtc": parse_date(row.get("RFSTDTC")), "rfpendtc": (row.get("RFPENDTC") or "").strip(), } # ODM extract: one element record per subject per study event, plus # the subject's first and last dosing dates (the same on every event). elements = {} subject_order = [] with open(f"{INPUT_DIR}/odm.csv", newline="", encoding="utf-8") as handle: for row in csv.DictReader(handle): subject = row["SubjectKey"] if subject not in elements: elements[subject] = {} subject_order.append(subject) record = elements[subject].setdefault( row["StudyEventOID"], { "studyid": row["StudyOID"], "usubjid": subject, "etcd": row["StudyEventOID"], "element": "", "taetord": "", "epoch": "", "firstdtc": "", "lastdtc": "", }, ) item = row["ItemOID"] value = (row.get("Value") or "").strip() if item == "IT.TE.ELEMENT": record["element"] = value elif item == "IT.TA.TAETORD": record["taetord"] = value elif item == "IT.TA.EPOCH": record["epoch"] = value elif item == "IT.EX.FIRSTDTC": record["firstdtc"] = value elif item == "IT.EX.LASTDTC": record["lastdtc"] = value rows = [] for subject in subject_order: subject_dm = dm.get(subject, {}) reference = subject_dm.get("rfstdtc") records = sorted( elements[subject].values(), key=lambda rec: (int(rec["taetord"]) if rec["taetord"] else 0), ) for record in records: epoch = record["epoch"] if epoch == "SCREENING": sestdtc = subject_dm.get("rficdtc", "") seendtc = record["firstdtc"] elif epoch == "TREATMENT": sestdtc = record["firstdtc"] seendtc = record["lastdtc"] else: sestdtc = record["lastdtc"] seendtc = subject_dm.get("rfpendtc", "") rows.append( { "DOMAIN": "SE", "STUDYID": record["studyid"], "USUBJID": record["usubjid"], "SESEQ": record["taetord"], "ETCD": record["etcd"], "ELEMENT": record["element"], "TAETORD": record["taetord"], "EPOCH": epoch, "SESTDTC": sestdtc, "SEENDTC": seendtc, "SESTDY": study_day(parse_date(sestdtc), reference), "SEENDY": study_day(parse_date(seendtc), reference), "SEUPDES": "", } ) columns = [ "DOMAIN", "STUDYID", "USUBJID", "SESEQ", "ETCD", "ELEMENT", "TAETORD", "EPOCH", "SESTDTC", "SEENDTC", "SESTDY", "SEENDY", "SEUPDES", ] with open(f"{OUTPUT_DIR}/se.csv", "w", newline="", encoding="utf-8") as handle: writer = csv.DictWriter(handle, fieldnames=columns) writer.writeheader() writer.writerows(rows)if __name__ == "__main__": main()solutions/sdtm-se-subject-elements/result.sas
Edit53 lines/* opensas reference solution for the yamaa benchmark sdtm-se-subject-elements. Reads the benchmark inputs and derives the requested output. Execute with the existing opensas runtime: opensas /app/output/result.sas. */data dm; length STUDYID USUBJID ARMCD RFICDTC RFSTDTC RFPENDTC $1024; infile "/app/input/dm.csv" dsd dlm="," firstobs=2 truncover lrecl=32767; input STUDYID : $char1024. USUBJID : $char1024. ARMCD : $char1024. RFICDTC : $char1024. RFSTDTC : $char1024. RFPENDTC : $char1024.;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 StudyEventOID; run;data elements; length ELEMENT ORD EPOCH $1024; retain ELEMENT ORD EPOCH; set ordered; by StudyOID SubjectKey StudyEventOID; if first.StudyEventOID then do; ELEMENT=''; ORD=''; EPOCH=''; end; if ItemOID='IT.TE.ELEMENT' then ELEMENT=Value; if ItemOID='IT.TA.TAETORD' then ORD=Value; if ItemOID='IT.TA.EPOCH' then EPOCH=Value; if last.StudyEventOID then output;run;proc sort data=odm out=ordered; by StudyOID SubjectKey; run;data dosing; length FIRSTDTC LASTDTC $1024; retain FIRSTDTC LASTDTC; set ordered; by StudyOID SubjectKey; if first.SubjectKey then do; FIRSTDTC=''; LASTDTC=''; end; if ItemOID='IT.EX.FIRSTDTC' then FIRSTDTC=Value; if ItemOID='IT.EX.LASTDTC' then LASTDTC=Value; if last.SubjectKey then output;run;proc sql; create table joined as select a.*,b.FIRSTDTC,b.LASTDTC,c.RFICDTC,c.RFSTDTC,c.RFPENDTC from elements a left join dosing b on a.StudyOID=b.StudyOID and a.SubjectKey=b.SubjectKey inner join dm c on a.StudyOID=c.STUDYID and a.SubjectKey=c.USUBJID where not missing(a.ELEMENT); quit;data result; set joined; length DOMAIN $2 STUDYID USUBJID ETCD SESTDTC SEENDTC SEUPDES $1024; DOMAIN='SE'; STUDYID=StudyOID; USUBJID=SubjectKey; ETCD=StudyEventOID; TAETORD=input(ORD,best32.); SESEQ=TAETORD; SEUPDES=''; SESTDY=.; SEENDY=.;if EPOCH='SCREENING' then do; SESTDTC=RFICDTC; SEENDTC=FIRSTDTC; end; else if EPOCH='TREATMENT' then do; SESTDTC=FIRSTDTC; SEENDTC=LASTDTC; end; else do; SESTDTC=LASTDTC; SEENDTC=RFPENDTC; end;if not missing(RFSTDTC) then do; if not missing(SESTDTC) then do; SESTDY=input(SESTDTC,yymmdd10.)-input(RFSTDTC,yymmdd10.); if SESTDY>=0 then SESTDY+1; end; if not missing(SEENDTC) then do; SEENDY=input(SEENDTC,yymmdd10.)-input(RFSTDTC,yymmdd10.); if SEENDY>=0 then SEENDY+1; end; end; run;proc sql; create table final as select DOMAIN, STUDYID, USUBJID, SESEQ, ETCD, ELEMENT, TAETORD, EPOCH, SESTDTC, SEENDTC, SESTDY, SEENDY, SEUPDES from result;quit;proc export data=final outfile="/app/output/se.csv" dbms=csv replace; run;
yamaa