***********************************************************************************************; ** Program Name : adcm.sas **; ** Date Created : 09Mar2021 **; ** Programmer Name : XIONGR03 **; ** Purpose : Create adcm dataset **; ** Input data : cm suppcm adsl **; ** Output data : adcm.sas7bdat **; ***********************************************************************************************; options mprint mlogic symbolgen mprint symbolgen mlogic nocenter missing=" "; proc datasets library=WORK kill nolist nodetails; quit; **Setup the environment**; %let oprot=/Volumes/app/cdars/prod/sites/cdars4/prjC459/nda2_unblinded_esub/bla_euaext_esub_sdtm/saseng/cdisc3_0; %let prot=/Volumes/app/cdars/prod/sites/cdars4/prjC459/nda2_unblinded_esub/bla_esub_adam/saseng/cdisc3_0; libname dataprot "&oprot./data" access=readonly; libname datvprot "&prot./data_vai"; libname viewpx "/Volumes/app/saseng/prod/cdisc3_0/view/" access=readonly; proc printto print="&prot./analysis/esub/output/adcm.rpt" log="&prot./analysis/esub/logs/adcm.log" new; run; proc sql noprint; select distinct(version) into :_dictver from viewpx.whodrug; quit; ******************************************************************************************; * Specification 2 *; * Merge SDTM with Supplemental dataset if Supplemental CM Dataset Exists *; * Abort the program if SUPPCM.DICTVER does not match WHODRUG.VERSION or *; * if SUPPCM does not have QNAM=DICTVER *; ******************************************************************************************; **hup02 modified to fix mapping issue; data cm; length CMSTDTC $20; set dataprot.cm; if CMTRT='' and CMSTDTC='' then delete; if length(CMSTDTC)=10 then CMSTDTC=strip(CMSTDTC)||"T23:59:59"; **to fix period issue when subject dosing 2 doses in the same day; run; proc sql noprint; select distinct QNAM into :_suppcm_keep_vars separated by " " from dataprot.suppcm; quit; *****************************************************************; *Specification 1: Reading INPUT SDTM and Supplemental Datasets *; *Subsetting Supplemental Dataset based on _supp_subset parameter*; *****************************************************************; data _spmdel_supp_dsin_subset; set dataprot.suppcm; run; data _spmdel_sdtm_ds; set cm; run; *******************************************************************************; *Specification : Supplemental Dataset will be merged with SDTM for all values*; *of IDVAR including missing values. *; * a. Find whether IDVAR has a missing a value *; * b. Calculate number of non-missing values for IDVAR *; * c. Checking whether non-missing value of IDVAR is character or Numeric *; *******************************************************************************; proc sql noprint; select NMISS(distinct idvar) into :_cntvar from _spmdel_supp_dsin_subset; select N(distinct idvar) into :_cntvar1 from _spmdel_supp_dsin_subset; quit; proc sql noprint; select distinct idvar into :_idvar1 - :_idvar1 from _spmdel_supp_dsin_subset where idvar is not missing; quit; data _spmdel_supp_dsin_subset_idvar1; set _spmdel_supp_dsin_subset; where idvar="CMSEQ"; run; ************************************************************; *Specification :Tranposing Supplemental Dataset *; ************************************************************; proc sort data=_spmdel_supp_dsin_subset_idvar1; by studyid usubjid idvar idvarval; quit; proc transpose data=_spmdel_supp_dsin_subset_idvar1 out=_spmdel_supp_dsin_idvar1_h; by studyid usubjid idvar idvarval; id qnam; idlabel qlabel; var qval; quit; ************************************************************; *Specification :Creating IDVAR from IDVARVAL *; ************************************************************; data _spmdel_temp(keep=CMSEQ); set _spmdel_sdtm_ds; run; data _spmdel_suppds1 (drop=idvar idvarval _NAME_ _LABEL_); set _spmdel_supp_dsin_idvar1_h; if idvar="CMSEQ"; CMSEQ=input(idvarval, best12.); run; proc sort data=_spmdel_sdtm_ds out=_ds1; by STUDYID USUBJID CMSEQ; run; proc sort data=_spmdel_suppds1 out=_ds2; by STUDYID USUBJID CMSEQ; run; data _spmdel_sdtm_temp_out1; merge _ds1(in=d1) _ds2(in=d2); by STUDYID USUBJID CMSEQ; if d1; run; **********************************************************************; *Specification : Final Merged output dataset *; **********************************************************************; data _condrug; set _spmdel_sdtm_temp_out1; run; proc sql noprint; select distinct(dictver) into :_supp_dictver from _condrug where dictver ne ''; quit; ******************************************************************************************; * Specification 4 *; * Derive the following variables: *; * ASTDT :Analysis Start Date *; * ASTDTF :Analysis Start Date Imputation Flag *; * ASTTM :Analysis Start Time *; * ASTTMF :Analysis Start Time Imputation Flag *; * AENDT :Analysis End Date *; * AENTM :Analysis End Time *; * AENDTF :Analysis End Date Imputation Flag *; * AENTMF :Analysis End Time Imputation Flag *; * ASTDTM :Analysis Start Date/Time *; * AENDTM :Analysis End Date/Time *; * Note: Time variables are not derived if time is not collected for any of the records *; ******************************************************************************************; proc sql noprint; select count(1) into :_start_time_exists from _condrug where length(compress(cmstdtc)) > 10; select count(1) into :_end_time_exists from _condrug where length(compress(cmendtc)) > 10; quit; data _condrug; set _condrug; if ^missing(CMSTDTC) then do; length yr $4 mm dd $2; yr=substr(CMSTDTC, 1, 4); mm=substr(CMSTDTC, 6, 2); dd=substr(CMSTDTC, 9, 2); ; if yr ne ' ' then do; dflag=' '; if (dd eq " " or dd eq "-T") and mm ne " " then do; dd='01'; dflag='D'; end; if mm eq " " or mm eq "--" then do; mm='01'; dd='01'; dflag='M'; end; newdate=(trim(left(yr))||'-'||trim(left(mm))||'-'||trim(left(dd))); ASTDT=input(newdate, ??is8601da.); format ASTDT date9.; ASTDTF=dflag; end; drop yr mm dd dflag newdate; end; if ^missing(CMENDTC) then do; length yr $4 mm dd $2; yr=substr(CMENDTC, 1, 4); mm=substr(CMENDTC, 6, 2); dd=substr(CMENDTC, 9, 2); ; if yr ne ' ' then do; dflag=' '; if (dd eq " " or dd eq "-T") and mm ne " " then do; fakedate=input(((trim(left(yr))||'-'||trim(left(mm))||'-'||'01')), ??is8601da.); format fakedate date9.; tempdate=intnx('month', fakedate, 1)-1; dd=strip(put(day(tempdate), best.)); dflag='D'; end; if (dd eq " " or dd eq "-T") and mm eq " " or mm eq "--" then do; mm='12'; dd='31'; dflag='M'; end; newdate=(trim(left(yr))||'-'||trim(left(mm))||'-'||trim(left(dd))); AENDT=input(newdate, ??is8601da.); format AENDT date9.; AENDTF=dflag; drop fakedate tempdate; end; drop yr mm dd dflag newdate; end; ******************************************************************************************; * SPECIFICATION 3 *; * -Process Time (if requested in macro call) *; * Substring isodate into hour, minutes and seconds. *; * Based upon _imputation_rule_time (start or stop), impute missing values in time. *; * If _imptimeflag is supplied in macro call, then the highest time imputed will *; * be populated. *; * If no time exists,then hour, minutes and seconds are imputed and flag will contain 'H'*; * if only hour exists,then minutes and seconds will be imputed and flag will contain 'M'*; * if hour and minutes exist, then seconds will be imputed and flag will contain 'S' *; ******************************************************************************************; if ^missing(CMSTDTC) then do; length hr mn sc $2 newtime $8; yr=substr(CMSTDTC, 1, 4); hr=substr(CMSTDTC, 12, 2); mn=substr(CMSTDTC, 15, 2); sc=substr(CMSTDTC, 18, 2); ; if yr ne ' ' then do; tflag=' '; if sc eq " " then do; sc='00'; tflag='S'; end; if mn eq " " then do; mn='00'; tflag='M'; end; if hr eq " " then do; hr='00'; tflag='H'; end; newtime=(trim(left(hr))||':'||trim(left(mn))||':'||trim(left(sc))); ASTTM=input(newtime, ??is8601tm.); format ASTTM time8.; ASTTMF=tflag; drop tflag; end; drop yr hr mn sc newtime; end; if ^missing(CMENDTC) then do; length hr mn sc $2 newtime $8; yr=substr(CMENDTC, 1, 4); hr=substr(CMENDTC, 12, 2); mn=substr(CMENDTC, 15, 2); sc=substr(CMENDTC, 18, 2); ; if yr ne ' ' then do; tflag=' '; if sc eq " " then do; sc='59'; tflag='S'; end; if mn eq " " then do; mn='59'; tflag='M'; end; if hr eq " " then do; hr='23'; tflag='H'; end; newtime=(trim(left(hr))||':'||trim(left(mn))||':'||trim(left(sc))); AENTM=input(newtime, ??is8601tm.); format AENTM time8.; AENTMF=tflag; drop tflag; end; drop yr hr mn sc newtime; end; ASTDTM=ifn(missing(ASTTM), ASTDT, dhms(ASTDT, 0, 0, ASTTM)); format ASTDTM datetime20.; drop AENTM AENTMF; run; *****************************************************************************************; * SPECIFICATION 1: *; * Protocol Specific Imputation Rules. *; *****************************************************************************************; data _ConDrug; set _ConDrug; run; *******************************************************************************************; * Specification 2 *; * Imputation of ApxxSTM/APxxETM/APxxSDTM/APxxEDTM based on Time collected or missing. *; *******************************************************************************************; Data _Null_; Do i=1 to 2; x=Strip(Put(i, 2.)); y=Strip(Put(i, z2.)); Call Symput(cats("_TRSDT", x), cats("TR", y, "SDT")); Call Symput(cats("_TREDT", x), cats("TR", y, "EDT")); Call Symput(cats("_TRSTM", x), cats("TR", y, "STM")); Call Symput(cats("_TRETM", x), cats("TR", y, "ETM")); Call Symput(cats("_APSDT", x), cats("AP", y, "SDT")); Call Symput(cats("_APEDT", x), cats("AP", y, "EDT")); Call Symput(cats("_APSTM", x), cats("AP", y, "STM")); Call Symput(cats("_APETM", x), cats("AP", y, "ETM")); Call Symput(cats("_APSDTM", x), cats("AP", y, "SDTM")); Call Symput(cats("_APEDTM", x), cats("AP", y, "EDTM")); Call Symput(cats("_TRSDTM", x), cats("TR", y, "SDTM")); Call Symput(cats("_TREDTM", x), cats("TR", y, "EDTM")); Call Symput(cats("_PrdxxN", x), y); End; Run; Data work.adsl; Set datvprot.adsl; If Missing(TR01STM) then _apx_TR01STM="00:00:00"t; Else _apx_TR01STM=TR01STM; If Missing(TR01ETM) then _apx_TR01ETM="23:59:59"t; Else _apx_TR01ETM=TR01ETM; If ^Missing(TR01SDT) then _apx_TR01SDTM=dhms(TR01SDT, 0, 0, _apx_TR01STM); If ^Missing(TR01EDT) then _apx_TR01EDTM=dhms(TR01EDT, 0, 0, _apx_TR01ETM); AP01SDT=datepart(_apx_TR01SDTM); AP01STM=timepart(_apx_TR01SDTM); If Missing(TR02STM) then _apx_TR02STM="00:00:00"t; Else _apx_TR02STM=TR02STM; If Missing(TR02ETM) then _apx_TR02ETM="23:59:59"t; Else _apx_TR02ETM=TR02ETM; If ^Missing(TR02SDT) then _apx_TR02SDTM=dhms(TR02SDT, 0, 0, _apx_TR02STM); If ^Missing(TR02EDT) then _apx_TR02EDTM=dhms(TR02EDT, 0, 0, _apx_TR02ETM); AP02SDT=datepart(_apx_TR02SDTM); AP02STM=timepart(_apx_TR02SDTM); if ^Missing(_apx_TR02SDTM-1) then do; _apx_TR01EDTM=min((_apx_TR02SDTM-1), (_apx_TR01EDTM+((365)*86400))); end; else _apx_TR01EDTM=_apx_TR01EDTM+((365)*86400); AP01EDT=datepart(_apx_TR01EDTM); AP01ETM=Timepart(_apx_TR01EDTM); AP01SDTM=dhms(AP01SDT, 0, 0, AP01STM); AP01EDTM=dhms(AP01EDT, 0, 0, AP01ETM); Attrib AP01SDT Label="Period 01 Start Date" AP01EDT Label="Period 01 End Date" AP01STM Label="Period 01 Start Time" AP01ETM Label="Period 01 End Time" AP01SDTM Label="Period 01 Start Datetime" AP01EDTM Label="Period 01 End Datetime"; Format AP01SDT AP01EDT date9. AP01STM AP01ETM time8. AP01SDTM AP01EDTM datetime20.; _apx_TR02EDTM=_apx_TR02EDTM+((365)*86400); AP02EDT=datepart(_apx_TR02EDTM); AP02ETM=Timepart(_apx_TR02EDTM); AP02SDTM=dhms(AP02SDT, 0, 0, AP02STM); AP02EDTM=dhms(AP02EDT, 0, 0, AP02ETM); Attrib AP02SDT Label="Period 02 Start Date" AP02EDT Label="Period 02 End Date" AP02STM Label="Period 02 Start Time" AP02ETM Label="Period 02 End Time" AP02SDTM Label="Period 02 Start Datetime" AP02EDTM Label="Period 02 End Datetime"; Format AP02SDT AP02EDT date9. AP02STM AP02ETM time8. AP02SDTM AP02EDTM datetime20.; run; ******************************************************************************************; *Specification *; *Create a list of all Treatment Time related column names from user input of G_ADSL_VARS *; *Create a Master List of all Treatment Time related column names from datvprot.adsl *; *Compare User list with Master List *; *Bailout if any of the columns of Master List are not specified by USER *; ******************************************************************************************; data _tmpcol2(keep=_usrlst); length _usrlst $20; drop _string; _string="SUBJID SITEID AGE AGEU SEX SEXN RACE RACEN ARACE ARACEN SAFFL COMPLFL ARM ARMCD ACTARM ACTARMCD TRTSDT TRTSTM TRTSDTM TRTEDT TRTETM TRTEDTM V01DT V02DT V03DT V04DT VAX101DT VAX10UDT VAX102DT VAX201DT VAX202DT COHORTN COHORT DOSALVLN DOSALVL DOSPLVLN DOSPLVL PHASEN PHASE UNBLNDDT TRTARN TRTAR TRTPRN TRTPR PROCGR1 PROCGR1N MULENRFL DS30KFL HIVFL AGETR01 AGEGR1 AGEGR1N AGEGR4 AGEGR4N TR01SDTM TR01EDTM TR02SDTM TR02EDTM TRT01A TRT01AN TRT01P TRT01PN TRT02A TRT02AN TRT02P TRT02PN VAX101 VAX102 VAX10U VAX201 VAX202 VAX20U VAX20UDT DS3KFL RANDFL RAND1FL SAF1FL SAF2FL AP01SDT AP01STM AP01SDTM AP01EDT AP01ETM AP01EDTM AP02SDT AP02STM AP02SDTM AP02EDT AP02ETM AP02EDTM"; do until(_usrlst=' '); _count+1; _usrlst=scan(_string, _count); output; end; run; proc sql noprint; create table _tmpcol4 as select distinct upcase(_usrlst) as _usrlst from _tmpcol2 where upcase(_usrlst) like 'TR%' or upcase(_usrlst) like 'AP%'; quit; proc contents data=work.adsl out=_tmpcol(keep=NAME) noprint; proc sql noprint; select distinct upcase(NAME) into : _masterlist separated by " " from _tmpcol where (upcase(name) like 'TR%' or upcase(name) like 'AP%') and (upcase(Name) in ('TRTEDT', 'TRTSDT', 'TRTETM', 'TRTSTM') or prxmatch('/AP\d{2}[EDT\b|SDT\b]/', Name) or prxmatch('/AP\d{2}[STM\b|ETM\b]/', Name) or prxmatch('/AP\d{2}[SDTM\b|EDTM\b]/', Name) ); quit; data _tmpcol3(keep=_mstrlst); length _mstrlst $20; drop _string; _string="AP01EDT AP01EDTM AP01ETM AP01SDT AP01SDTM AP01STM AP02EDT AP02EDTM AP02ETM AP02SDT AP02SDTM AP02STM TRTEDT TRTETM TRTSDT TRTSTM"; do until(_mstrlst=' '); _count+1; _mstrlst=scan(_string, _count); output; end; run; proc sql noprint; select distinct(a._mstrlst) into :_usrlst_missing separated by ' ' from _tmpcol3 as a where a._mstrlst not in (select _usrlst from _tmpcol4); quit; proc sql noprint; create table _list_ (name char(32)); insert into _list_ values("G_VEXIST") values(""); select name into:G_NOMATCH separated by ' ' from _list_ where name not in (select name from dictionary.macros); drop table _list_; quit; data _null_; length _retlist _retlst2 $2000 _column $40; dsid=open(upcase("WORK.ADSL")); i=1; do while (scan("USUBJID SUBJID SITEID AGE AGEU SEX SEXN RACE RACEN ARACE ARACEN SAFFL ARM ARMCD ACTARM ACTARMCD TRTSDT TRTSTM TRTSDTM TRTEDT TRTETM TRTEDTM V01DT V02DT V03DT V04DT VAX101DT VAX10UDT VAX102DT VAX201DT VAX202DT COHORTN COHORT DOSALVLN DOSALVL DOSPLVLN DOSPLVL PHASEN PHASE UNBLNDDT MULENRFL DS30KFL HIVFL AGETR01 AGEGR1 AGEGR1N AGEGR4 AGEGR4N TR01SDTM TR01EDTM TR02SDTM TR02EDTM TRT01A TRT01AN TRT01P TRT01PN TRT02A TRT02AN TRT02P TRT02PN VAX101 VAX102 VAX10U VAX201 VAX202 VAX20U VAX20UDT DS3KFL RANDFL RAND1FL SAF1FL SAF2FL AP01SDT AP01STM AP01SDTM AP01EDT AP01ETM AP01EDTM AP02SDT AP02STM AP02SDTM AP02EDT AP02ETM AP02EDTM TR01SDT TR01STM TR01SDTM TR01EDT TR01ETM TR01EDTM TR02SDT TR02STM TR02SDTM TR02EDT TR02ETM TR02EDTM",i,'') > ''); _column = upcase(scan("USUBJID SUBJID SITEID AGE AGEU SEX SEXN RACE RACEN ARACE ARACEN SAFFL ARM ARMCD ACTARM ACTARMCD TRTSDT TRTSTM TRTSDTM TRTEDT TRTETM TRTEDTM V01DT V02DT V03DT V04DT VAX101DT VAX10UDT VAX102DT VAX201DT VAX202DT COHORTN COHORT DOSALVLN DOSALVL DOSPLVLN DOSPLVL PHASEN PHASE UNBLNDDT MULENRFL DS30KFL HIVFL AGETR01 AGEGR1 AGEGR1N AGEGR4 AGEGR4N TR01SDTM TR01EDTM TR02SDTM TR02EDTM TRT01A TRT01AN TRT01P TRT01PN TRT02A TRT02AN TRT02P TRT02PN VAX101 VAX102 VAX10U VAX201 VAX202 VAX20U VAX20UDT DS3KFL RANDFL RAND1FL SAF1FL SAF2FL AP01SDT AP01STM AP01SDTM AP01EDT AP01ETM AP01EDTM AP02SDT AP02STM AP02SDTM AP02EDT AP02ETM AP02EDTM TR01SDT TR01STM TR01SDTM TR01EDT TR01ETM TR01EDTM TR02SDT TR02STM TR02SDTM TR02EDT TR02ETM TR02EDTM",i,'')); if varnum(dsid, _column) then do; _retlist=trim(left(_retlist))||' '||_column; _retlst2=trim(left(_retlst2))||'/'||_column; end; i=i+1; end; dsid=close(dsid); call symput('g_vexist', trim(left(compbl(_retlist)))); call symput('g_vexist2', trim(left(_retlst2))||'/'); run; *******************************************************************************; * SPECIFICATION - Merge the datasets. *; * 1.Sort the datasets by key merge-by variables. *; * 2.Merge the datasets using full join, inner join,left join or right join. *; * Default is full join. *; * 3.Generate a list of subjects not having any matching observations based on *; * key-by variables. *; *******************************************************************************; proc sort data=_condrug out=_ds1; by USUBJID; run; proc sort data=work.adsl out=_ds2; by USUBJID; run; data _condrug; merge _ds1(in=d1) _ds2(in=d2 keep= Usubjid SUBJID SITEID AGE AGEU SEX SEXN RACE RACEN ARACE ARACEN SAFFL ARM ARMCD ACTARM ACTARMCD TRTSDT TRTSTM TRTSDTM TRTEDT TRTETM TRTEDTM V01DT V02DT V03DT V04DT VAX101DT VAX10UDT VAX102DT VAX201DT VAX202DT COHORTN COHORT DOSALVLN DOSALVL DOSPLVLN DOSPLVL PHASEN PHASE UNBLNDDT MULENRFL DS30KFL HIVFL AGETR01 AGEGR1 AGEGR1N AGEGR4 AGEGR4N TR01SDTM TR01EDTM TR02SDTM TR02EDTM TRT01A TRT01AN TRT01P TRT01PN TRT02A TRT02AN TRT02P TRT02PN VAX101 VAX102 VAX10U VAX201 VAX202 VAX20U VAX20UDT DS3KFL RANDFL RAND1FL SAF1FL SAF2FL AP01SDT AP01STM AP01SDTM AP01EDT AP01ETM AP01EDTM AP02SDT AP02STM AP02SDTM AP02EDT AP02ETM AP02EDTM TR01SDT TR01STM TR01SDTM TR01EDT TR01ETM TR01EDTM TR02SDT TR02STM TR02SDTM TR02EDT TR02ETM TR02EDTM ) ; by USUBJID; if d1; run; ******************************************************************************************; * Specification *; * Derive the following variables: *; * PREFL :Pre-treatment Flag *; * ONPERFL :On-Period Flag *; * ONTRXXFL :On-Period XX Flag *; * ASTDY :Analysis Start Relative Day *; * AENDY :Analysis End Relative Day *; * Note: As per CR 137592, If Time collected in Condrug then use DTM vars when deriving *; * ONPERFL variable. *; * Updated PREFL by removing the logic handling CMSTRF *; ******************************************************************************************; data adcm; set _condrug; if ASTDT < AP01SDT then PREFL='Y'; if n(ap01sdtm) and (((ASTDTM <=AP01EDTM) and ((AENDT >=AP01SDT) or (upcase(CMENRTPT)='ONGOING'))) or ((ASTDTM >=AP01SDTM) and (ASTDTM <=AP01EDTM))) then do; ONTR01FL='Y'; ONPERFL='Y'; end; label ONTR01FL="On-Period 01 Flag"; if n(ap02sdtm) and (((ASTDTM <=AP02EDTM) and ((AENDT >=AP02SDT) or (upcase(CMENRTPT)='ONGOING'))) or ((ASTDTM >=AP02SDTM) and (ASTDTM <=AP02EDTM))) then do; ONTR02FL='Y'; ONPERFL='Y'; end; label ONTR02FL="On-Period 02 Flag"; ******************************************************************************************; * Specification 1 *; * Calculate the study day using the dates supplied by the user. *; ******************************************************************************************; If ^Missing(AstDt) and ^Missing(TrtSdt) then do; If AstDt lt TrtSdt then AstDy=AstDt - TrtSdt; Else If AstDt ge TrtSdt then AstDy=AstDt - TrtSdt + 1; end; If ^Missing(AenDt) and ^Missing(TrtSdt) then do; If AenDt lt TrtSdt then AenDy=AenDt - TrtSdt; Else If AenDt ge TrtSdt then AenDy=AenDt - TrtSdt + 1; end; run; ******************************************************************************************; * Specification 7 *; * Merge WHODRUG Dictionary with SDTM *; * Get ATC Level Code/Names from WHODRUG *; ******************************************************************************************; data whodrug; set viewpx.whodrug; run; proc sql noprint; select max(length(drugname)) into: _len from whodrug; quit; data whodrug; set whodrug(rename=(drugname=drugname_)); length temp drugname drgname1 $200; temp=substr(drugname_, 1, 200); reverse=reverse(temp); pos=indexc(reverse, ",. "); if substr(reverse(temp), 1, 1) in (" ", ".", ",") or substr(drugname_, 201, 1) in (" ", ".", ",") then do; val_1=temp; rval_1=substr(drugname_, 201); end; else do; val_1=substr(temp, 1, 200-pos+1); rval_1=substr(drugname_, 200-pos+2); end; drugname=val_1; if length(rval_1) le 200 then drgname1=rval_1; else if length(rval_1) gt 200 then drugname_=rval_1; run; proc sql noprint; create table _all as select a.*, b.drugname, b.drgname1, b.atc1name as ATC1T length=200 informat=$200., b.atc2name as ATC2T length=200 informat=$200., b.atc3name as ATC3T length=200 informat=$200., b.atc4name as ATC4T length=200 informat=$200., b.atc5name as ATC5T length=200 informat=$200., b.atc1code as ATC1CD, b.atc2code as ATC2CD, b.atc3code as ATC3CD, b.atc4code as ATC4CD, b.atc5code as ATC5CD from adcm as a left join whodrug as b on a.cmcode=b.drugcode; quit; *****************************************************************************************; * Specification 7.1 *; * STUDY SPECIFIC VARIABLES/FLAGS DERIVATION *; * CMOPIDFL FLAG DERIVATION *; ****************************************************************************************; data _all; set _all; length VPHASE $100.; label VPHASE="Vaccine Phase" VPHASEN="Vaccine Phase(N)" VAXNO="CM Occured after Which Vaccination"; if (ASTDT=VAX201DT>.) then do; if (prefl='Y' and vax101dt ne .) or (astdt ne . and vax101dt=.) then VPHASE='Pre-Vaccination'; else if (VAX101DT>. and ((VAX101DT<=ASTDT<=V01DT and coalesce(vax102dt,vax10udt)=.) or (VAX101DT<=ASTDTV02DT>. then VPHASE='Follow Up 2'; end; else do; if (astdt ne . and vax201dt=.) or (unblnddt<=astdt. and ((VAX201DT<=ASTDT<=V03DT and vax202dt=.) or (VAX201DT<=ASTDTV04DT>. then VPHASE='Follow Up 4'; end; if CMSTDTC='' then VPHASE=''; if VPHASE='Pre-Vaccination' then VPHASEN=0; else if VPHASE='Vaccination 1' then VPHASEN=1; else if VPHASE='Vaccination 2' then VPHASEN=2; else if VPHASE='Follow Up 1' then VPHASEN=3; else if VPHASE='Follow Up 2' then VPHASEN=99; else if VPHASE='After unblinding and before Vaccination 3' then VPHASEN=4; else if VPHASE='Vaccination 3' then VPHASEN=5; else if VPHASE='Vaccination 4' then VPHASEN=6; else if VPHASE='Follow Up 3' then VPHASEN=7; else if VPHASE='Follow Up 4' then VPHASEN=100; if vphasen in (3, 99) then do; if vax102dt ne . then VAXNO=2; else if vax101dt ne . then VAXNO=1; end; else if vphasen in (7, 100) then do; if vax202dt ne . then VAXNO=4; else if vax201dt ne . then VAXNO=3; end; else if vphasen in (5, 6) then do; VAXNO=vphasen-2; end; else if vphasen in (1,2) then VAXNO=vphasen; else if vphasen in (4) then do; if .=99 then do; ONTR01FL=''; ONTR02FL=''; ONPERFL=''; end; if ONTR01FL='Y' or ONTR02FL='Y' then ONPERFL='Y'; else ONPERFL=''; proc sort; by USUBJID CMSEQ; run; data _all; set _all; cmstdtc=strip(scan(cmstdtc, 1, "T")); run; proc sort data=_all; by usubjid cmseq; quit; data datvprot.adcm(label='Concomitant Medications Analysis Dataset'); retain STUDYID USUBJID SUBJID SITEID CMSEQ CMCAT CMSCAT CMSTDTC CMENDTC CMTRT CMDECOD CMCODE PREFL ONPERFL ONTR01FL ONTR02FL ASTDT ASTDTF ASTTM ASTTMF ASTDTM ASTDY AENDT AENDTF AENDY CMCLAS CMCLASCD DRUGNAME DRGNAME1 ATC1CD ATC1T ATC2CD ATC2T ATC3CD ATC3T ATC4CD ATC4T ATC5CD ATC5T CMSTDY CMENDY CMDOSE CMROUTE CMDOSTXT CMDOSU CMDOSFRQ CMENRTPT CMENTPT EPOCH DICTVER CMCLAS1 CMCLAS2 CMCLSCD1 CMCLSCD2 CMCODE DICTVER USUBJID SUBJID SITEID AGE AGEU SEX SEXN RACE RACEN ARACE ARACEN SAFFL ARM ARMCD ACTARM ACTARMCD TRTSDT TRTSTM TRTSDTM TRTEDT TRTETM TRTEDTM V01DT V02DT V03DT V04DT VAX101DT VAX10UDT VAX102DT VAX201DT VAX202DT COHORTN COHORT DOSALVLN DOSALVL DOSPLVLN DOSPLVL PHASEN PHASE UNBLNDDT MULENRFL DS30KFL HIVFL AGETR01 AGEGR1 AGEGR1N AGEGR4 AGEGR4N TR01SDTM TR01EDTM TR02SDTM TR02EDTM TRT01A TRT01AN TRT01P TRT01PN TRT02A TRT02AN TRT02P TRT02PN VAX101 VAX102 VAX10U VAX201 VAX202 VAX20U VAX20UDT DS3KFL RANDFL RAND1FL SAF1FL SAF2FL; set _all(keep = STUDYID USUBJID SUBJID SITEID CMSEQ CMCAT CMSCAT CMSTDTC CMENDTC CMTRT CMDECOD CMCODE PREFL ONPERFL ONTR01FL ONTR02FL ASTDT ASTDTF ASTTM ASTTMF ASTDTM ASTDY AENDT AENDTF AENDY CMCLAS CMCLASCD DRUGNAME DRGNAME1 ATC1CD ATC1T ATC2CD ATC2T ATC3CD ATC3T ATC4CD ATC4T ATC5CD ATC5T CMSTDY CMENDY CMDOSE CMROUTE CMDOSTXT CMDOSU CMDOSFRQ CMENRTPT CMENTPT EPOCH DICTVER CMCLAS1 CMCLAS2 CMCLSCD1 CMCLSCD2 CMCODE DICTVER USUBJID SUBJID SITEID AGE AGEU SEX SEXN RACE RACEN ARACE ARACEN SAFFL ARM ARMCD ACTARM ACTARMCD TRTSDT TRTSTM TRTSDTM TRTEDT TRTETM TRTEDTM V01DT V02DT V03DT V04DT VAX101DT VAX10UDT VAX102DT VAX201DT VAX202DT COHORTN COHORT DOSALVLN DOSALVL DOSPLVLN DOSPLVL PHASEN PHASE UNBLNDDT MULENRFL DS30KFL HIVFL AGETR01 AGEGR1 AGEGR1N AGEGR4 AGEGR4N TR01SDTM TR01EDTM TR02SDTM TR02EDTM TRT01A TRT01AN TRT01P TRT01PN TRT02A TRT02AN TRT02P TRT02PN VAX101 VAX102 VAX10U VAX201 VAX202 VAX20U VAX20UDT DS3KFL RANDFL RAND1FL SAF1FL SAF2FL VPHASE VPHASEN VAXNO); label DRUGNAME = 'WHODrug preferred name' DRGNAME1 = "WHODrug preferred name1" ATC1CD = 'ATC Level 1 Code' ATC1T = 'ATC Level 1 Text' ATC2CD = 'ATC Level 2 Code' ATC2T = 'ATC Level 2 Text' ATC3CD = 'ATC Level 3 Code' ATC3T = 'ATC Level 3 Text' ATC4CD = 'ATC Level 4 Code' ATC4T = 'ATC Level 4 Text' ATC5CD = 'ATC Level 5 Code' ATC5T = 'ATC Level 5 Text' ASTDT = 'Analysis Start Date' ASTTM = 'Analysis Start Time' ASTDTM = 'Analysis Start Date/Time' ASTTMF = 'Analysis Start Time Imputation Flag' ASTDTF = 'Analysis Start Date Imputation Flag' ASTDY = 'Analysis Start Relative Day' AENDT = 'Analysis End Date' AENDTF = 'Analysis End Date Imputation Flag' AENDY = 'Analysis End Relative Day' PREFL = 'Pre-treatment Flag' ONPERFL = 'On-Period Flag' CMCODE = 'Standardized Medication Code' ; drop ASTDTM ASTTM ASTTMF; run; proc printto; run;