***********************************************************************************************; ** Program Name : adae-vax-tier2-p3-saf.sas **; ** Date Created : 22Mar2021 **; ** Programmer Name : LIL233 **; ** Purpose : Create adae-vax-tier2-p3-saf **; ** Input data : adae **; ** Output data : adae-vax-tier2-p3-saf.html **; ***********************************************************************************************; options mprint mlogic symbolgen mprint symbolgen mlogic nocenter missing=" "; **Setup the environment**; %let prot=/Volumes/app/cdars/prod/sites/cdars4/prjC459/nda2_unblinded_esub/bla_esub_adam/saseng/cdisc3_0; libname datvprot "&prot./data_vai" access=readonly; %let codename=adae-vax-tier2-p3-saf; %let outlog=&prot./analysis/esub/logs/&codename..log; %let outtable=&prot./analysis/esub/output/&codename..html; proc printto log="&outlog." new; run; data g_a_dsin; set datvprot.adae; analysis_subset='Y'; where AECAT='ADVERSE EVENT' and VPHASEN in (1, 2) and V01DT >=ASTDT and (UNBLNDDT=. or UNBLNDDT > ASTDT) and agegr3n ne . and MULENRFL ne "Y" and HIVFL ne "Y"; run; data g_adsl_dsin; set datvprot.adsl; where saffl="Y" and phasen ne 1 and agegr3n ne . and MULENRFL ne "Y" and HIVFL ne "Y"; run; data __trtmap; length trtcode trtdecd $100; if 0 then set g_adsl_dsin(keep=TRT01AN); trtval=1; if vtype(TRT01AN)='C' then trtcode=tranwrd(compbl(quote("8")), ' ', '" "'); else trtcode="8"; trtdecd="BNT162b2 (30 (*ESC*){unicode 03BC}g)"; trtvar="TRT01AN"; trtlbl="TRT01A"; output; trtval=2; if vtype(TRT01AN)='C' then trtcode=tranwrd(compbl(quote("9")), ' ', '" "'); else trtcode="9"; trtdecd="Placebo"; trtvar="TRT01AN"; trtlbl="TRT01A"; output; stop; run; data g_adsl_dsin; set g_adsl_dsin; if TRT01AN in (8) then do; newtrtn=1; newtrt=coalescec("BNT162b2 (30 (*ESC*){unicode 03BC}g)", TRT01A); output; end; if TRT01AN in (9) then do; newtrtn=2; newtrt=coalescec("Placebo", TRT01A); output; end; run; proc sort data=g_adsl_dsin; by usubjid newtrtn; run; data g_a_dsin; set g_a_dsin; if TRT01AN in (8) then do; newtrtn=1; newtrt=coalescec("BNT162b2 (30 (*ESC*){unicode 03BC}g)", TRT01A); output; end; if TRT01AN in (9) then do; newtrtn=2; newtrt=coalescec("Placebo", TRT01A); output; end; run; proc format; value $_f_ "[1]"="[1]" "[2]"="[2]" "[3]"="[3]" "[4]"="[4]" "[5]"="[5]" "[6]"="[6]" "[7]"="[7]" "[8]"="[8]" "[9]"="[9]"; value $_f1_ "[1]"="[1]" "[2]"="[2]" "[3]"="[3]" "[4]"="[4]" "[5]"="[5]" "[6]"="[6]" "[7]"="[7]" "[8]"="[8]" "[9]"="[9]"; run; quit; data g_a_dsin1; set g_a_dsin; where ^missing(aeterm); if missing(aedecod) then aedecod=aeterm; if missing(AEBODSYS) then AEBODSYS='**Uncoded Terms Being Queried'; if missing(AEDECOD) then AEDECOD='**Uncoded Terms Being Queried'; aebodsys=upcase(substr(aebodsys, 1, 1))||strip(upcase(substr(aebodsys, 2, (length(aebodsys)-1)))); run; proc sort data=g_a_dsin1 out=_a_dsin nodupkey; by newtrtn usubjid aedecod astdt ATOXGR; run; proc sort data=_a_dsin; by newtrtn usubjid AEBODSYS AEDECOD; run; data _a_dsin; set _a_dsin; by newtrtn usubjid AEBODSYS AEDECOD; if first.usubjid then _anyae=1; if aeterm ne '' then _event=1; _uniqid=_n_; proc sort; by usubjid newtrtn; run; data final; merge g_adsl_dsin(in=d1) _a_dsin(in=d2); by usubjid newtrtn; if d1; if nmiss(_anyae) then _anyae=0; if nmiss(_event) then _event=0; proc sort; by newtrtn; run; proc sql; create table trtlist as select distinct newtrtn, newtrt from final order by newtrtn; quit; data trtlist; set trtlist nobs=ntrts; if upcase(newtrtn)=2 then _control=1; run; proc sort; by _control newtrtn; run; data trtlist; set trtlist; if _control then _trt_id=0; else _trt_id=_n_; proc sort; by newtrtn; run; data final_t; merge final(in=a) trtlist(in=b); by newtrtn; if a; run; data final; set final_t; where _trt_id in (0, 1); run; data _data1; set final; where (NEWTRTN is not missing); proc sort; by NEWTRTN USUBJID; run; data _data1; retain _trt 0; length _str $200; _datasrt=1; set _data1 end=eof; by NEWTRTN USUBJID; drop _str; _str=' '; _lastby=1; _dummyby=0; if first.NEWTRTN then do; if not missing(NEWTRTN) then do; _trt=_trt + 1; end; _str=NEWTRT; end; proc sort; by _datasrt; run; proc sort data=_data1 out=_bydat1(keep=_datasrt _dummyby) nodupkey; by _datasrt; run; data _bydat1; set _bydat1 end=eof; by _datasrt; _byvar1=0; length _bycol _byindnt $50 _bylast $10; _bycol=" "; _byindnt=" "; _bylast=" "; run; proc sort data=_data1 out=bign nodupkey; by _trt usubjid; run; proc summary data=bign nway; class _trt; var _trt; output out=_denom (drop=_freq_ _type_) n=npts; run; proc sort data=_data1; by AEBODSYS AEDECOD; run; proc sort data=_data1 out=dc2 nodupkey; by usubjid _trt AEBODSYS AEDECOD; run; proc summary data=dc2 nway; class _trt AEBODSYS AEDECOD; var _trt; output out=smln2(drop=_type_ _freq_) n=count2; run; proc sort data=smln2; by _trt; run; data final2; merge smln2 _denom; by _trt; if count2 > 0 then do; pct=round(((count2/npts)*100), .01); end; else pct=.; run; proc sql; create table seldt2 as select AEBODSYS, AEDECOD , max(pct) as _maxpct2 from final2 group by AEBODSYS, AEDECOD; quit; data _data1; merge _data1(in=a) seldt2(in=b); by AEBODSYS AEDECOD; run; data _data1; set _data1; attrib _PCTCOFF format=1. label='Records meeting % cutoff flag'; if _maxpct2 ge 1.0 then _PCTCOFF=1; else _PCTCOFF=0; _obsnum=_n_; run; proc sort data=_data1 out=_ANYAE_pct_1; by _trt usubjid; where _pctcoff=1; run; proc sort data=_data1 out=_ANYAE_subs_1(keep=_trt usubjid) nodupkey; by _trt usubjid; where _ANYAE>0; run; data _sumdat1; merge _ANYAE_pct_1(in=a drop=_ANYAE) _ANYAE_subs_1(in=b); by _trt usubjid; if a and b; run; data _sumdat1; set _sumdat1; by _trt usubjid; if first.usubjid then _ANYAE=1; keep _trt usubjid _obsnum _ANYAE; proc sort; by _obsnum; run; proc sort data=_data1; by _obsnum; run; data _data1; merge _data1(in=a rename=(_ANYAE=__ANYAE)) _sumdat1(keep=_obsnum _ANYAE); by _obsnum; _ANYAE=ifn(_ANYAE=1, 1, 0); if a; run; proc sort data=_data1(drop=_obsnum); by _trt usubjid; run; data dsin; set _data1; _cat=1; run; data frame; set _bydat1(keep=); _cat=1; _trt=1; output; _cat=1; _trt=2; output; run; proc sort data=frame; by _cat _trt; run; data _denom1(drop=_col) _temp1; _trt=1; _cat=1; output _denom1; _col=_trt; output _temp1; _trt=2; _cat=1; output _denom1; _col=_trt; output _temp1; run; proc sql; create table denom as select a.*, b.npts as trtn, b.npts as subgrpn from _denom1 as a left join _denom as b on a._trt=b._trt; create table temp as select a.*, b.npts as trtn, b.npts as subgrpn from _temp1 as a left join _denom as b on a._trt=b._trt; quit; proc sql noprint; create table numin as select a.*, b._col from dsin as a left join temp as b on a._trt=b._trt; quit; data numin; set numin; where aeterm is not missing and _pctcoff in (1); run; proc sort data=numin out=class1(keep=AEBODSYS) nodupkey; by AEBODSYS; run; data classo1; set frame; do i=1 to cobs; set class1 nobs=cobs point=i; output; end; run; proc sort data=numin out=level1 NODUPKEY; by _cat _trt AEBODSYS usubjid; run; proc summary data=level1 nway classdata=classo1 missing; class _cat _trt AEBODSYS; output out=count1(drop=_type_ rename=(_freq_=count)); run; data sort1; set class1; AEBODSYS_n=_n_; run; proc sort data=count1; by AEBODSYS; run; proc sort data=sort1 out=sorto1(keep=AEBODSYS AEBODSYS_n); by AEBODSYS; run; data countf1; length _rwlabel $800; merge count1 sorto1; by AEBODSYS; _level=1; _rwlabel=AEBODSYS; run; proc sort data=numin out=class2(keep=AEBODSYS AEDECOD) nodupkey; by AEBODSYS AEDECOD; run; data classo2; set frame; do i=1 to cobs; set class2 nobs=cobs point=i; output; end; run; proc sort data=numin out=level2 NODUPKEY; by _cat _trt AEBODSYS AEDECOD usubjid; run; proc summary data=level2 nway classdata=classo2 missing; class _cat _trt AEBODSYS AEDECOD; output out=count2(drop=_type_ rename=(_freq_=count)); run; proc sort data=level2 out=flevel2 nodupkey; by AEBODSYS AEDECOD usubjid; where _COL=1; run; proc summary data=flevel2 nway classdata=class2 missing; class AEBODSYS AEDECOD; output out=fcount2(drop=_type_ rename=(_freq_=count)); run; proc sort data=fcount2 out=freq2(keep=AEBODSYS AEDECOD count); by descending count AEBODSYS AEDECOD; run; data sort2; set freq2; AEDECOD_n=_n_; run; proc sort data=count2; by AEBODSYS AEDECOD; run; proc sort data=sort2 out=sorto2(keep=AEBODSYS AEDECOD AEDECOD_n); by AEBODSYS AEDECOD; run; data countf2; length _rwlabel $800; merge count2 sorto2; by AEBODSYS AEDECOD; _level=2; _rwlabel=repeat(byte(160), 5)||AEDECOD; run; proc sort data=countf2; by AEBODSYS; run; data countf2; merge countf2 sorto1; by AEBODSYS; run; data alln; set countf1 countf2; run; proc sort data=denom out=denomf(keep=_trt trtn) nodupkey; by _trt; run; proc sort data=alln out=alln; by _trt; run; data final; merge alln(in=a) denomf; by _trt; if a; length _cvalue $30; if count > . then _cvalue=put(count, 5.); else _cvalue=put(0, 5.); if count > 0 and trtn > 0 then do; pct=(count/trtn)*100; _cvalue=trim(_cvalue)||" ("||strip(put(pct, 5.1))||")"; end; if length(_cvalue) < 13 then do; substr(_cvalue, 13, 1)='A0'x; end; proc sort; by _cat _trt AEBODSYS_n AEDECOD_n; run; data _base1; set final; by _cat _trt AEBODSYS_n AEDECOD_n; if first._trt then _rowsrt=0; _rowsrt++1; _indent=coalesce(0, 0); _dptindt=coalesce(0, 0); _datasrt=1; _blcksrt=0+ AEBODSYS_n; proc sort; by _datasrt _blcksrt _rowsrt; run; data _cnp _tmp_cnp; set _base1; if count=. then count=0; indc=1; output _cnp; indc=2; count=trtn - count; output _cnp; if indc=2 and count=0 then output _tmp_cnp; run; proc sort data=_cnp; by _cat AEBODSYS AEDECOD _rowsrt _rwlabel _trt; run; proc sort nodupkey data=_tmp_cnp(keep=_cat AEBODSYS AEDECOD _rowsrt _rwlabel _trt); by _cat AEBODSYS AEDECOD _rowsrt _rwlabel _trt; run; proc freq data=_cnp noprint; by _cat AEBODSYS AEDECOD _rowsrt _rwlabel _trt; table indc/binomial alpha=0.05; output out=obsprop binomial; weight count; run; data obsprop; merge obsprop _tmp_cnp(in=a); by _cat AEBODSYS AEDECOD _rowsrt _rwlabel _trt; if _bin_=1 and not a then do; xl_bin_=1 - xu_bin; xu_bin_=1 - xl_bin; end; else do; xl_bin_=xl_bin; xu_bin_=xu_bin; end; run; data cnpobsprop2(keep=_cat AEBODSYS AEDECOD _rowsrt _rwlabel _trt cnp_ci); set obsprop; by _cat AEBODSYS AEDECOD _rowsrt _rwlabel _trt; cnp_ci='(' || compress(put(xl_bin_ * 100, 5.1)) || ',(*ESC*){nbspace 1}' || compress(put(xu_bin_ * 100, 5.1)) || ')'; label cnp_ci='95% CI'; proc sort; by _cat AEBODSYS AEDECOD _rowsrt _rwlabel _trt; run; proc sort data=_base1; by _cat AEBODSYS AEDECOD _rowsrt _rwlabel _trt; run; data _base1; merge _base1(in=a) cnpobsprop2; by _cat AEBODSYS AEDECOD _rowsrt _rwlabel _trt; if a; run; /* proc format; */ /* picture pval (round) 0 - < 0.001 = '<.001' (noedit) 0.001 - 0.99 = '00009.999' 0.99 < - high = '>.99' (noedit) -1 = 'N/A' ; */ /* run; */ ********************************************************************************; * SPECIFICATION 2 *; * - Assign flag of 1 to all records in input dataset. *; * - Output same records with flag of 2 & populate count by substracting *; * counts from big N. *; ********************************************************************************; data _binom; set _base1; if count=. then count=0; YesNo=1; output; YesNo=2; count=trtn - count; output; run; proc sql noprint; create table _binom1 as select a.*, b._trt_id from _binom a left join (select distinct _trt, _trt_id from _data1) b on a._trt=b._trt; quit; proc sort data=_binom1; by _datasrt _level _rowsrt _trt_id; run; proc binomial noprint data=_binom1 gamma=0.000001 out=mnm_diffprop ti=10 su=1 alpha=0.95; riskdiff / as one STD; by _datasrt _level _rowsrt; po _trt_id; ou yesno; weight count; run; data mnm_stat; set mnm_diffprop; where upcase(test)="PD_AS_ONE_STD" and upcase(item) in ('STAT' 'ASLWRDIF' 'ASUPRDIF' 'ASMPVAL2'); keep _datasrt _level _rowsrt item value; run; proc sort data=mnm_stat; by _datasrt _level _rowsrt item; run; proc transpose data=mnm_stat out=trp_mnm_stat (drop=_name_ _label_); by _datasrt _level _rowsrt; var value; id item; run; data mnmdiffprop2(keep=_datasrt _level _rowsrt mnmdiff mnmci mnmpval); set trp_mnm_stat; by _datasrt _level _rowsrt; mnmdiff=strip(put((STAT*100), 8.1)); if ASLWRDIF ne . and ASUPRDIF ne . then mnmci='('||strip(put((ASLWRDIF*100), 6.1))||', ' ||strip(put((ASUPRDIF*100), 6.1))|| ')'; mnmpval=strip(put(ASMPVAL2, PVALUE6.4)); run; proc sort data=_base1; by _level _rowsrt; run; proc sort data=mnmdiffprop2; by _level _rowsrt; run; data _base1; merge _base1(in=a) mnmdiffprop2; by _level _rowsrt; if a; run; data _base1; set _base1; if aedecod=' ' then do; _cvalue=' '; cnp_ci=' '; mnmdiff=' '; mnmci=' '; end; proc sort; by _rowsrt; run; data _base1c(keep=_datasrt _rowsrt _ctrlval _ctrlci); set _base1; where _trt=2; rename _cvalue=_ctrlval cnp_ci=_ctrlci; proc sort; by _rowsrt; run; data _base1; merge _base1(in=a where=(_trt^=2)) _base1c; by _rowsrt; if a; run; data _stat1; set _base1; run; data _null_; set _denom; if _trt=1 then call symput("trtn1", npts); if _trt=2 then call symput("trtn2", npts); run; %put &trtn1.; %put &trtn2.; options nodate nocenter nonumber; options topmargin=0.75in bottommargin=0.75in leftmargin=0.75in rightmargin=0.75in; options orientation=LANDSCAPE papersize="LETTER"; ods escapechar="~"; option nobyline; title1 "Tier 2 Adverse Events Reported From Dose 1 to 1 Month After Dose 2, by System Organ Class and Preferred Term (*ESC*){unicode 2013}"; title2 "Blinded Placebo-Controlled Follow-up Period (*ESC*){unicode 2013} Phase 2/3 Subjects (*ESC*){Unicode 2265}16 Years of Age (*ESC*){unicode 2013} Safety Population"; footnote1 "Note: MedDRA (v23.1) coding dictionary applied."; footnote2 "Note: Tier 2 events are %nrbquote("common") adverse events with an incidence rate (*ESC*){unicode 2265}1.0% in any vaccine group (preferred term level). No Tier 1 events were identified at this stage for this program."; footnote3 "Note: The 95% confidence interval quantifies the precision of the risk difference estimate. Confidence intervals are not adjusted for multiplicity. They should only be used to identify potentially important adverse events."; footnote4 "%nrbquote(a.~{nbspace 5}N = number of subjects in the specified group. This value is the denominator for the percentage calculations. )"; footnote5 "%nrbquote(b.~{nbspace 5}n = Number of subjects reporting at least 1 occurrence of the specified adverse event.)"; footnote6 "%nrbquote(c.~{nbspace 5}Exact 2-sided CI based on the Clopper and Pearson method.)"; footnote7 "%nrbquote(d.~{nbspace 5}Difference in proportions, expressed as a percentage (BNT162b2 [30 (*ESC*){unicode 03BC}g] - placebo).)"; footnote8 "%nrbquote(e.~{nbspace 5}2-Sided CI, based on the Miettinen and Nurminen method for the difference in proportions, expressed as a percentage.)"; ods html file="&outtable."; proc report data=work._stat1 ls=132 ps=60 split="|" nocenter missing contents=""; column (_datasrt _blcksrt _rowsrt (" " _rwlabel) ("Vaccine Group (as Administered)~{line}" (("BNT162b2 (30 (*ESC*){unicode 03BC}g)|(N(*ESC*){super a}=&trtn1.)" (_cvalue cnp_ci) ) ("Placebo|(N(*ESC*){super a}=&trtn2.)" (_ctrlval _ctrlci) ) ) ) ("Difference" (mnmdiff mnmci)) ); define _datasrt / group order=internal noprint; define _blcksrt / group order=internal noprint; define _rowsrt / group order=internal noprint; define _rwlabel / group "System Organ Class|~{nbspace 5}Preferred Term" order=data style(column)={just=left} style(header)={just=left} left; define _cvalue / group nozero "n(*ESC*){super b} (%)" style(column)={leftmargin=12px} style(header)={just=center} center; define cnp_ci / group nozero "(95% CI(*ESC*){super c})" style(column)={leftmargin=12px} style(header)={just=center} center; define _ctrlval / group nozero "n(*ESC*){super b} (%)" style(column)={leftmargin=12px} style(header)={just=center} center; define _ctrlci / group nozero "(95% CI(*ESC*){super c})" style(column)={leftmargin=12px} style(header)={just=center} center; define mnmdiff / group nozero "%(*ESC*){super d}" style(column)={leftmargin=12px} style(header)={just=center} center; define mnmci / group nozero "(95% CI(*ESC*){super e})" style(column)={leftmargin=12px} style(header)={just=center} center; run; ods HTML close; proc printto; run;