*************************************************************************************************; * * CLIENT: ModernaTX, Inc. * PROTOCOL: mRNA-1273-P201 * * PURPOSE: Create analysis dataset adlb * * INPUT FILES: SDTM domains * OUTPUT FILES: adlb.sas7bdat * * USAGE NOTES: * *************************************************************************************************; * (c) 2020 PPD * All Rights Reserved. *************************************************************************************************; options noquotelenmax; %include "madam.sas"; **Assign global macro variable DSETNAME to reflect the name of the final ADaM dataset**; %global DSETNAME; %let dsetname = adlb; %let adslvar=tr01sdt tr01edt dose2dt dos2dtm tr01sdtm tr01edtm dose1fl dose2fl eosdt dthdt randfl sex; **Merge supplemental data onto parent domain**; %revsupp(libin=trans,libout=work,ds=lb,supp=supplb,outds=lb_all); proc sort tagsort data=lb_all; by usubjid subjid lbcat lbtestcd lbdtc; where missing(lbstat) and not missing(lbtestcd); run; proc sort tagsort data=trans.sv out=sv nodupkey; by usubjid subjid visit svstdtc; where (index(visit,'Visit 7 ') or index(visit,'Visit 4')) and ^missing(svstdtc) and ^missing(visitdy); run; data sv; set sv; by usubjid subjid visit svstdtc; if first.visit then output; run; proc sort data = adb.adsl out = adsl (keep = USUBJID subjid &adslvar.) nodupkey ; by usubjid; run; **INSERT CODE TO GENERATE DATASET**; data lb_adsl; merge lb_all(in=a) adsl (in=b) sv(where=(index(_visit4,'Visit 4')) rename=(domain=_dom_v4 visit=_visit4 svstdtc=_svstdtc4) keep=usubjid subjid domain visit svstdtc) sv(where=(index(_visit7,'Visit 7')) rename=(domain=_dom_v7 visit=_visit7 svstdtc=_svstdtc7) keep=usubjid subjid domain visit svstdtc); by usubjid subjid; if a and b; run; proc sort tagsort data=lb_adsl; by usubjid lbdtc lbtestcd; run; data lb_adsl; length _war $200 PARAMCD $8 PARAM $100 PARCAT1 $50 ANRIND CRIT1 $20 ; set lb_adsl; by usubjid lbdtc lbtestcd; if missing(lborres) then do; _war='Put Aler'||'t_R: LBORRES is missing when '||strip(subjid)||', LBTESTCD='|| strip(lbtestcd)||', LBCAT='||strip(lbcat)||', LBDTC='||strip(lbdtc)||'.'; put _war; end; PARCAT1 = lbcat; ANRIND = lbnrind; ANRLO = lbstnrlo; ANRHI = lbstnrhi; * paramcd; if lbcat='CHEMISTRY' and lbtestcd='HCG' and lbmethod=:'ELE' then PARAMCD = 'ECLIAHCG'; else if lbcat='CHEMISTRY' and lbtestcd='HCG' and lbmethod=:'CHEM' then PARAMCD = 'CHEMIHCG'; else if lbcat='URINALYSIS' then PARAMCD = 'U'||lbtestcd; else PARAMCD = lbtestcd; * param; if lbcat='CHEMISTRY' and lbtestcd='HCG' and ^missing(lbstresu) then PARAM = strip(lbmethod)||' '||strip(lbtest)||' ('||strip(lbstresu)||')'; else if lbcat='CHEMISTRY' and lbtestcd='HCG' then PARAM = strip(lbmethod)||' '||strip(lbtest); else if lbcat='URINALYSIS' and ^missing(lbstresu) then PARAM = 'Urinary '||strip(lbtest)||' ('||strip(lbstresu)||')'; else if lbcat='URINALYSIS' then PARAM = 'Urinary '||strip(lbtest); else if ^missing(lbstresu) then PARAM = strip(lbtest)||' ('||strip(lbstresu)||')'; else PARAM = lbtest; * results AVAL; if index(lbstresc,'<') then do; DTYPE = 'HALFLLOQ'; AVAL = input(substr(lbstresc,2),best.)*0.5; end; else if index(lbstresc,'>') then do; DTYPE = 'ULOQ'; AVAL = input(substr(lbstresc,2),best.); end; else AVAL = lbstresn; * _avaln; if ^missing(lbstresc) then _avaln = 1; else _avaln = 0; * Criterion 1 Evaluation Result Flag: ALP, BILI; if PARAMCD in ('ALP' ) and cmiss(AVAL,ANRHI)=0 then do; if AVAL/ANRHI<2 then CRIT1FL = 'Y'; if AVAL/ANRHI<2 then CRIT1 = strip(PARAMCD)||' <2 x ULN'; end; if PARAMCD in ('BILI') and cmiss(AVAL,ANRHI)=0 then do; if AVAL/ANRHI>=2 then CRIT1FL = 'Y'; if AVAL/ANRHI>=2 then CRIT1 = strip(PARAMCD)||' >=2 x ULN'; end; * Criterion 1 Evaluation Result Flag: ALT, AST; else if PARAMCD in ('ALT' 'AST') and cmiss(AVAL,ANRHI)=0 then do; if AVAL/ANRHI>3 then CRIT1FL = 'Y'; if AVAL/ANRHI>3 then CRIT1 = strip(PARAMCD)||' >3 x ULN'; end; * Analysis Date/time; %ISO2SAS(isodate=LBDTC, datec=_lbdtc, daten=ADT, timec=_atmc); if ^missing(_atmc) then ATM = input(_atmc,time5.); if ^missing(_atmc) and ^missing(ADT) then ADTM = input(compress(put(ADT,date9.)||':'||_atmc),datetime20.); if ADT>=TR01SDT>. then ADY = ADT - TR01SDT + 1; else if .0 and ^missing(TR01SDT) then postfl='Y'; _adtmy = abs(_adtmy); *Most Recent Dose Reference; if .=DOSE2DT>. then MRDDY = ADT - DOSE2DT + 1; else if .=tr01sdt>. then do; _war='Put Aler'||'t_R: MDOSREF needs update. '; put _war USUBJID= PARAMCD= LBDTC= TR01SDT= ; put _war TR01SDTM= TR01EDT TR01EDTM= DOSE2DT=; put _war DOS2DTM= visit=; end; * Analysis Toxicity Grade Low; if PARAMCD in ('HGB' 'WBC' 'LYM' 'NEUT' 'PLAT') and ^missing(AVAL) then do; _war='Put Aler'||'t_R: ATOXGRL needs update.'; _aval = AVAL*1000; if param='Hemoglobin (g/L)' then do; _aval = AVAL*0.1; if sex='F' and 11.0<=_aval<=12.0 then _atoxgrln_aval = 1; else if sex='F' and 9.5<=_aval<=10.9 then _atoxgrln_aval = 2; else if sex='F' and 8.0<=_aval<=9.4 then _atoxgrln_aval = 3; else if sex='F' and _aval<8.0 then _atoxgrln_aval = 4; else if sex='F' and 8<=_aval<=12 then put _war usubjid= sex= paramcd= _aval= param=; else if sex='F' then _atoxgrln_aval = 0; else if sex='M' and 12.5<=_aval<=13.5 then _atoxgrln_aval = 1; else if sex='M' and 10.5<=_aval<=12.4 then _atoxgrln_aval = 2; else if sex='M' and 8.5<=_aval<=10.4 then _atoxgrln_aval = 3; else if sex='M' and _aval<8.5 then _atoxgrln_aval = 4; else if sex='M' and 8.5<=_aval<=13.5 then put _war usubjid= sex= paramcd= _aval= param=; else if sex='M' then _atoxgrln_aval = 0; else put _war usubjid= sex= paramcd= _aval= param=; end; else if param='Leukocytes (10^9/L)' then do; if 2500<=_aval<=3500 then ATOXGRLN = 1; else if 1500<=_aval<=2499 then ATOXGRLN = 2; else if 1000<=_aval<=1499 then ATOXGRLN = 3; else if _aval<1000 then ATOXGRLN = 4; else if 1000<=_aval<=3500 then put _war usubjid= sex= paramcd= _aval= param=; else ATOXGRLN = 0; end; else if param='Lymphocytes (10^9/L)' then do; if 750<=_aval<=1000 then ATOXGRLN = 1; else if 500<=_aval<=749 then ATOXGRLN = 2; else if 250<=_aval<=499 then ATOXGRLN = 3; else if _aval<250 then ATOXGRLN = 4; else if 250<=_aval<=1000 then put _war usubjid= sex= paramcd= _aval= param=; else ATOXGRLN = 0; end; else if param='Neutrophils (10^9/L)' then do; if 1500<=_aval<=2000 then ATOXGRLN = 1; else if 1000<=_aval<=1499 then ATOXGRLN = 2; else if 500<=_aval<=999 then ATOXGRLN = 3; else if _aval<500 then ATOXGRLN = 4; else if 500<=_aval<=2000 then put _war usubjid= sex= paramcd= _aval= param=; else ATOXGRLN = 0; end; else if param='Platelets (10^9/L)' then do; if 125000<=_aval<=140000 then ATOXGRLN = 1; else if 100000<=_aval<=124000 then ATOXGRLN = 2; else if 25000<=_aval<=99000 then ATOXGRLN = 3; else if _aval<25000 then ATOXGRLN = 4; else if 25000<=_aval<=140000 then put _war usubjid= sex= paramcd= _aval= param=; else ATOXGRLN = 0; end; else put _war usubjid= sex= paramcd= _aval= param=; if ^missing(ATOXGRLN) then ATOXGRL = 'Grade '||strip(put(ATOXGRLN,best.)); end; * Analysis Toxicity Grade High; retain _alt _ast; if PARAMCD in ('UREAN' 'CREAT' 'ALP' 'ALT' 'AST' 'BILI' 'EOS' 'PT' 'APTT' 'WBC') and ^missing(AVAL) then do; _war='Put Aler'||'t_R: ATOXGRH needs update.'; if param='Urea Nitrogen (mmol/L)' then do; if lowcase(lborresu)='mg/dl' then _aval = input(lborres,best.); else do; _war='Put Aler'||'t_P: _aval is missing when '; put _war SUBJID= PARAMCD= LBORRES= LBORRESU=; end; if 23<=_aval<=26 then ATOXGRHN = 1; else if 26<_aval<=31 then ATOXGRHN = 2; else if _aval>31 then ATOXGRHN = 3; else ATOXGRHN = 0; end; else if param='Creatinine (umol/L)' then do; if lowcase(lborresu)='mg/dl' then _aval = input(lborres,best.); else do; _war='Put Aler'||'t_P: _aval is missing when '; put _war SUBJID= PARAMCD= LBORRES= LBORRESU=; end; if 1.5<=_aval<=1.7 then ATOXGRHN = 1; else if 1.7<_aval<=2.0 then ATOXGRHN = 2; else if 2.0<_aval<=2.5 then ATOXGRHN = 3; else ATOXGRHN = 0; end; else if param='Alkaline Phosphatase (U/L)' and ^missing(lbstnrhi) then do; _aval = AVAL; if 1.1*lbstnrhi<=_aval<=2.0*lbstnrhi then ATOXGRHN = 1; else if 2.0*lbstnrhi<_aval<=3.0*lbstnrhi then ATOXGRHN = 2; else if 3.0*lbstnrhi<_aval<=10*lbstnrhi then ATOXGRHN = 3; else if _aval>10*lbstnrhi then ATOXGRHN = 4; else ATOXGRHN = 0; end; else if param in ('Alanine Aminotransferase (U/L)' 'Aspartate Aminotransferase (U/L)') and ^missing(lbstnrhi) then do; _aval = AVAL; if 1.1*lbstnrhi<=_aval<=2.5*lbstnrhi then ATOXGRHN = 1; else if 2.5*lbstnrhi<_aval<=5.0*lbstnrhi then ATOXGRHN = 2; else if 5.0*lbstnrhi<_aval<=10*lbstnrhi then ATOXGRHN = 3; else if _aval>10*lbstnrhi then ATOXGRHN = 4; else ATOXGRHN = 0; if param='Alanine Aminotransferase (U/L)' then _alt=ATOXGRHN; if param='Aspartate Aminotransferase (U/L)' then _ast=ATOXGRHN; end; else if param='Leukocytes (10^9/L)' then do; _aval = AVAL*1000; if 10800<=_aval<=15000 then ATOXGRHN = 1; else if 15001<=_aval<=20000 then ATOXGRHN = 2; else if 20001<=_aval<=25000 then ATOXGRHN = 3; else if _aval>25000 then ATOXGRHN = 4; else if 10800<=_aval<=25000 then put _war usubjid= sex= paramcd= _aval= param=; else ATOXGRHN = 0; end; else if param='Eosinophils (10^9/L)' then do; _aval = AVAL*1000; if 650<=_aval<=1500 then ATOXGRHN = 1; else if 1501<=_aval<=5000 then ATOXGRHN = 2; else if _aval>5000 then ATOXGRHN = 3; else if 650<=_aval<=5000 then put _war usubjid= sex= paramcd= _aval= param=; else ATOXGRHN = 0; end; else if param='Prothrombin Time (sec)' and ^missing(lbstnrhi) then do; _aval = AVAL; if 1.0*lbstnrhi<_aval<=1.10*lbstnrhi then ATOXGRHN = 1; else if 1.10*lbstnrhi<_aval<=1.20*lbstnrhi then ATOXGRHN = 2; else if 1.20*lbstnrhi<_aval<=1.25*lbstnrhi then ATOXGRHN = 3; else if _aval>1.25*lbstnrhi then ATOXGRHN = 4; else ATOXGRHN = 0; end; else if param='Activated Partial Thromboplastin Time (sec)' and ^missing(lbstnrhi) then do; _aval = AVAL; if 1.0*lbstnrhi<_aval<=1.2*lbstnrhi then ATOXGRHN = 1; else if 1.2*lbstnrhi<_aval<=1.4*lbstnrhi then ATOXGRHN = 2; else if 1.4*lbstnrhi<_aval<=1.5*lbstnrhi then ATOXGRHN = 3; else if _aval>1.5*lbstnrhi then ATOXGRHN = 4; else ATOXGRHN = 0; end; else if param='Bilirubin (umol/L)' and ^missing(lbstnrhi) then do; _aval = AVAL; if 1.1*lbstnrhi<=_aval<=1.25*lbstnrhi then _atoxgrhn_1 = 1; else if 1.25*lbstnrhi<_aval<=1.5*lbstnrhi then _atoxgrhn_1 = 2; else if 1.5*lbstnrhi<_aval<=1.75*lbstnrhi then _atoxgrhn_1 = 3; else if _aval>1.75*lbstnrhi then _atoxgrhn_1 = 4; else _atoxgrhn_1 = 0; if 1.1*lbstnrhi<=_aval<=1.5*lbstnrhi then _atoxgrhn_0 = 1; else if 1.5*lbstnrhi<_aval<=2.0*lbstnrhi then _atoxgrhn_0 = 2; else if 2.0*lbstnrhi<_aval<=3.0*lbstnrhi then _atoxgrhn_0 = 3; else if _aval>3.0*lbstnrhi then _atoxgrhn_0 = 4; else _atoxgrhn_0 = 0; end; else put _war usubjid= sex= paramcd= _aval= param= lbstnrhi=; if ^missing(ATOXGRHN) then ATOXGRH = 'Grade '||strip(put(ATOXGRHN,best.)); end; if last.lbdtc and paramcd^='BILI' then do; _alt=.; _ast=.; end; format ADTM datetime20. ADT date9. ATM time5.; run; proc sort tagsort data=lb_adsl out=base_chg; by usubjid paramcd descending _avaln postfl _adtmy descending lbseq; run; data base_chg; length AVISIT ATOXDSCL ATOXDSCH SHIFT1 SHIFT2 $50 AWRANGE $20 ASTAGE $30; set base_chg; by usubjid paramcd descending _avaln postfl _adtmy descending lbseq; * Baseline Record Flag; retain BASE BNRIND; if first.paramcd and _avaln=1 and prefl='Y' then do; ABLFL = 'Y'; AVISIT = 'Baseline'; BASE = AVAL; BNRIND = ANRIND; end; else if first.paramcd then do; BASE = .; BNRIND = ''; end; if lbblfl ne ablfl then do; _war='Put Aler'||'t_C: usubjid='||strip(usubjid)||', paramcd='||strip(paramcd)||' has ABLFL ne lbblfl.'|| ' Currently this record is not considered as baseline/post-baseline, CHG is missing.'; put _war lbblfl= ABLFL= LBDTC= TR01SDTM= TR01SDT= prefl= postfl= LBSTRESC=; end; * Change from Baseline; if postfl='Y' and cmiss(AVAL,BASE)=0 then CHG = AVAL - BASE; if postfl='Y' and cmiss(AVAL,BASE)=0 and BASE^=0 then PCHG = CHG/BASE*100; if postfl='Y' and BASE=0 then do; _war='Put Aler'||'t_C: PCHG is missing. '; put _war usubjid= paramcd= base= aval=; end; * Analysis Toxicity Grade Low; if param='Hemoglobin (g/L)' then do; _war='Put Aler'||'t_R: ATOXGRL needs update.'; if ^missing(CHG) then do; _aval = CHG*0.1; if -1.5<=_aval<0 then _atoxgrln_chg = 1; else if -2<=_aval<=-1.6 then _atoxgrln_chg = 2; else if -5<=_aval<=-2.1 then _atoxgrln_chg = 3; else if _aval<-5 then _atoxgrln_chg = 4; else if -5<=_aval<0 then put _war usubjid= sex= paramcd= _aval= param=; else _atoxgrln_chg = 0; end; if _atoxgrln_aval>=_atoxgrln_chg then ATOXGRLN = _atoxgrln_aval; else if _atoxgrln_chg>_atoxgrln_aval then ATOXGRLN = _atoxgrln_chg; else if cmiss(_atoxgrln_chg,_atoxgrln_aval)<2 then put _war usubjid= _atoxgrln_chg= _atoxgrln_aval= lbdtc=; if ^missing(ATOXGRLN) then ATOXGRL = 'Grade '||strip(put(ATOXGRLN,best.)); end; * ATOXGRH,Analysis Toxicity Grade High; if param='Bilirubin (umol/L)' and (_alt>1 or _ast>1) then ATOXGRHN = _atoxgrhn_1; else if param='Bilirubin (umol/L)' and (_alt=0 and _ast=0) then ATOXGRHN = _atoxgrhn_0; /* per protocol, Grade 1 will not be used for hematology values due to the large overlap with normal values at the central laboratory. */ else if param='Bilirubin (umol/L)' and ATOXGRHN = . and aval ne . then ATOXGRHN = 0; else if param='Bilirubin (umol/L)' and cmiss(_alt,_ast)<2 and not (_alt=1 or _ast=1) then do; _war='Put Aler'||'t_C: ATOXGRH is missing when PARAMCD=BILI. '; put _war usubjid= _ast= _alt= lbdtc= ATOXGRH=; end; if ^missing(ATOXGRHN) then ATOXGRH = 'Grade '||strip(put(ATOXGRHN,best.)); * Baseline Record Flag; retain BTOXGRL BTOXGRLN BTOXGRH BTOXGRHN; if first.paramcd and _avaln=1 and prefl='Y' then do; BTOXGRL = ATOXGRL; BTOXGRLN = ATOXGRLN; BTOXGRH = ATOXGRH; BTOXGRHN = ATOXGRHN; end; else if first.paramcd then do; BTOXGRLN = .; BTOXGRL = ''; BTOXGRHN = .; BTOXGRH = ''; end; * Change from Baseline; * Analysis Toxicity Description Low or Hight; if .=44 then AVISIT = 'Day 57'; if missing(visit) and ^missing(avisit) then do; _war='Put Aler'||'t_R: spec needs udpate because AVISIT='||strip(avisit)||' while VISIT is missing.'; put _war; end; end; else if postfl='Y' and ady>1 then AVISIT = 'Day '||scan(visit,4); *Analysis Visit (N); if AVISIT='Baseline' then AVISITN = 1; else if AVISIT='Day 29' then AVISITN = 5; else if AVISIT='Day 57' then AVISITN = 8; else if ^missing(AVISIT) then do; _war='Put Aler'||'t_R: AVISIT='||strip(avisit)||' while AVISITN is missing.'; put _war VISIT= ADY= LBDTC= TR01SDT= TR01SDTM= subjid=; end; * Analysis Window Valid Relative Range; if AVISIT='Baseline' then AWRANGE = '<=1 Pre-dose'; else if AVISIT='Day 29' then AWRANGE = 'Day 2 - Day 43'; else if AVISIT='Day 57' then AWRANGE = '>= Day 44'; * Analysis Window Target; if AVISIT='Baseline' then AWTARGET = 1; else if AVISIT='Day 29' then AWTARGET = 29; else if AVISIT='Day 57' then AWTARGET = 57; * Analysis Window Diff from Target; if cmiss(AWTARGET,ADY)=0 then AWTDIFF = abs(ADY - AWTARGET); if cmiss(AWTARGET,ADY)=0 then AWU = 'DAYS'; if postfl='Y' and (index(visit,'Uns') or missing(visit)) then do; _uns=1; _awtdiff=awtdiff; end; else if postfl='Y' then do; _uns=0; _awtdiff=0; end; else _awtdiff=99999999; * Stage; %ISO2SAS(isodate=_svstdtc4, datec=_svstdtc_4, daten=_svstdtn4, timec=_sv4tm); if ^missing(_sv4tm) and ^missing(_svstdtn4) then _svstdtm4 = input(compress(put(_svstdtn4,date9.)||':'||_sv4tm),datetime20.); %ISO2SAS(isodate=_svstdtc7, datec=_svstdtc_7, daten=_svstdtn7, timec=_sv7tm); if ^missing(_sv7tm) and ^missing(_svstdtn7) then _svstdtm7 = input(compress(put(_svstdtn7,date9.)||':'||_sv7tm),datetime20.); if randfl='Y' and ADT>=datepart(tr01sdtm) then do; if dose1fl='Y' and dose2fl='Y' then do; if nmiss(eosdt,_svstdtn7,dthdt) = 0 then enddate = min(eosdt, _svstdtn7,dthdt); if nmiss(eosdt,_svstdtn7) = 0 and dthdt = . then enddate = min(eosdt, _svstdtn7); if nmiss(eosdt,_svstdtn7,dthdt) = 2 and eosdt ne . then enddate = eosdt; if nmiss(eosdt,_svstdtn7,dthdt) = 2 and _svstdtn7 ne . then enddate = _svstdtn7; end; if dose1fl='Y' and dose2fl ne 'Y' then do; if nmiss(eosdt,_svstdtn4,dthdt) = 0 then enddate = min(eosdt, _svstdtn4,dthdt); if nmiss(eosdt,_svstdtn4) = 0 and dthdt = . then enddate = min(eosdt, _svstdtn4); if nmiss(eosdt,_svstdtn4,dthdt) = 2 and eosdt ne . then enddate = eosdt; if nmiss(eosdt,_svstdtn4,dthdt) = 2 and _svstdtn7 ne . then enddate = _svstdtn4; end; if dose1fl='Y' and dose2fl='Y' and enddate = . and postfl='Y' then ASTAGE = 'Vaccination stage'; else if dose1fl='Y' and dose2fl='Y' and (ADT>_svstdtn7>. or ADTM>_svstdtm7>.) then ASTAGE = 'Follow up stage'; else if dose1fl='Y' and dose2fl='Y' and ADT>=tr01sdt>. and ADT <= enddate then ASTAGE = 'Vaccination stage'; else if dose1fl='Y' and dose2fl='Y' and ADT>=dose2dt>. and enddate = . and ^missing(_svstdtc4) then ASTAGE = 'Vaccination stage'; else if dose1fl='Y' and dose2fl^='Y' and enddate = . and postfl='Y' then ASTAGE = 'Vaccination stage'; else if dose1fl='Y' and dose2fl^='Y' and (ADT>_svstdtn4>. or ADTM>_svstdtm4>.) then ASTAGE = 'Follow up stage'; else if dose1fl='Y' and dose2fl^='Y' and ADT>=tr01sdt>. and ADT <= enddate then ASTAGE = 'Vaccination stage'; else if dose1fl='Y' and dose2fl^='Y' and ADT>=tr01sdt>. and enddate = . then ASTAGE = 'Vaccination stage'; else do; _war='Put Alert'||'t_R: ASTAGE is missing when '; put _war subjid= dose1fl= dose2fl= lbdtc= tr01sdtm= tr01sdt= ; put _war tr01edtm= dose2dt= dos2dtm= _svstdtc4= _svstdtc7=; end; end; * Stage (N); if ASTAGE='Vaccination stage' then ASTAGEN = 1; else if ASTAGE='Follow up stage' then ASTAGEN = 2; run; * Analysis Flag 01; proc sort tagsort data=base_chg out=anl01fl; by usubjid paramcd avisitn descending postfl descending _avaln _uns _awtdiff descending _adtmy; run; data anl01fl; set anl01fl; by usubjid paramcd avisitn descending postfl descending _avaln _uns _awtdiff descending _adtmy; if first.avisitn and ^missing(avisitn) and postfl='Y' and _avaln=1 then ANL01FL = 'Y'; if ABLFL='Y' then ANL01FL='Y'; run; * Analysis Flag 02; proc sort tagsort data=anl01fl; by usubjid paramcd descending postfl astagen descending atoxgrln avisitn visitnum adt adtm _adtmy lbseq; run; data anl01fl; set anl01fl; by usubjid paramcd descending postfl astagen descending atoxgrln avisitn visitnum adt adtm _adtmy lbseq; if first.paramcd and postfl='Y' and astagen=1 and ^missing(atoxgrln) then ANL02FL = 'Y'; run; * Analysis Flag 03; proc sort tagsort data=anl01fl; by usubjid paramcd descending postfl astagen descending atoxgrhn avisitn visitnum adt adtm _adtmy lbseq; run; data adlb; set anl01fl; by usubjid paramcd descending postfl astagen descending atoxgrhn avisitn visitnum adt adtm _adtmy lbseq; if first.paramcd and postfl='Y' and astagen=1 and ^missing(atoxgrhn) then ANL03FL = 'Y'; keep STUDYID USUBJID LBSEQ LBDTC ADT ATM ADTM ADY VISIT VISITNUM AVISIT AVISITN ASTAGE ASTAGEN PARCAT1 PARAMCD PARAM AVAL BASE CHG PCHG AWRANGE AWTARGET AWTDIFF AWU LBORNRLO LBORNRHI LBORRES LBTOXGR LBSTRESC ATOXGRL ATOXGRLN ATOXGRH ATOXGRHN BTOXGRL BTOXGRLN BTOXGRH BTOXGRHN ATOXDSCL ATOXDSCH SHIFT1 SHIFT2 ANRIND BNRIND ANRLO ANRHI CRIT1 CRIT1FL ABLFL ANL01FL ANL02FL ANL03FL DTYPE MDOSREF MRDDY lborresu subjid; run; **Generate final dataset by updating certain attributes. Optionally merge common variables & create sequence variable as needed**; %TRTA(dsname=&DSETNAME); %adam_dataset_update( ds=&DSETNAME, libin=work, libout=output, adsllib=adb, addcomvar=Y, addseq=, dropinfmt=Y, mapspecfile=&ADAM_SPEC, maploc=&ADAM_SPEC_LOC, debug=N ); %macro dod; **Generate Value Level Metadata values for the ad dataset**; % dod_vlm( type=ADAM, selmems=&DSETNAME, excmems=, specloc=&G_PROJECTPATH.&G_TOPLEVEL.\Documents\Specs\, specname=&G_NICKNAME._ADaM_Spec.xlsm, debug=N ); **Generate Enhanced Controlled Terminology for the ad dataset**; % dod_enhcd_ct( type=ADAM, selmems=&DSETNAME, excmems=, specloc=&G_PROJECTPATH.&G_TOPLEVEL.\Documents\Specs\, specname=&G_NICKNAME._ADaM_Spec.xlsm, map_ct_nm=, map_ct_loc=, debug=N ); %mend;