************************************************************************ * CLIENT: ModernaTX, Inc. * PROTOCOL: mRNA-1273-P201 * PURPOSE: Create Table 14.2.1.1.12.1 Summary of Binding Antibody Levels Specific to SARS-CoV-2 Spike Protein by ELISA Per-Protocol Set * * INPUT FILES: adb.adsl adb.adis * OUTPUT FILES: t1402010101201.rtf * USAGE NOTES: ************************************************************************* * Copyright 2020 PPD * All Rights Reserved. *************************************************************************; *** Customize for this table ***; dm 'log;clear;output;clear'; proc datasets lib= work kill; run; * Subsetting where clause; %let where = PPBABFL="Y" and PARCAT1='Serum SARS-CoV-2 Binding Antibodies' and PPBABRFL='Y' and ANL01FL='Y' and index(PARAMCD,'V65IGG'); %let _default_bign_in_where = PPBABFL="Y"; *** Defaults ***; %include "modmrna1273p201_IA_defaults.sas"; %include "mgm_ci.sas"; %include "mclopper.sas"; %include "mmwintext.sas"; %let _default_in_data = adis; %let _default_debug = Y; %let _default_help = Y; %let _default_report_options = nowd missing spacing=1 split="&_default_prcode_split" ; %let subgroup = ; %let _DEFAULT_TRTVAR = TRT01PN; ** Formats here **; proc format; value $avisit (notsorted) 'OL-Day 1' = 'Baseline' 'OL-Day 8' = 'OL-Day 8' 'OL-Day 15' = 'OL-Day 15' 'OL-Day 29' = 'OL-Day 29' 'OL-Day 57' = 'OL-Day 57' 'OL-Day 209' = 'OL-Day 209' ; run; %process_indata(out_data=adis, in_data=adb.adis, bigndata=, trtvar=&_default_trtvar., type=table); %Header(Type=A); * ==== Subgroup ; * subgroup variable; %let subgroup =; %let subgrp_preloadfmt =; * title used for the subgroup; %let subgroup_title =; * symbol to use for alignment; %let align_symbol = ; %let _default_report_options = nowd missing spacing=1 split="&_default_prcode_split" ; %let _DEFAULT_PAGE_LENGTH_LINES = 58; ** column 1 header or label ; %let _default_col1_width_pcnt = 20; %let _default_col1_label = Timepoint&_default_escapechar.n Data Category&_default_escapechar.n Statistic; data adis; set adis; where &where.; run; ** For summ stats **; data adis_; set adis; where index(paramcd,"LV")=0; run; data adsl; set adsl; where &_default_bign_in_where.; proc sort nodupkey; by _all_; run; proc sql noprint; ***Subgroup Title***; create table Subgroup as select distinct param, paramcd, strip(put(LOD, best.)) as LOD, strip(put(ISLLOQ, best.)) as ISLLOQ, strip(put(ULOQ, best.)) as ULOQ from adis_ ; quit; data Subgroup; length subtitle $100.; set Subgroup; subtitle = 'Antibody: '||strip(param)||' (LLOQ: '||strip(ISLLOQ)||', ULOQ: '||strip(ULOQ)||')'; N= _n_; sec = strip(put(N,best.)); run; ** For CI **; %gmt_gmr_ci(datain=ADIS, subset=&where. and substr(param,1,5) = 'LOG10', dataout=adis_ci); %clopper(datain=ADIS, subset= substr(param,1,5) ^= 'LOG10' and &where. , crit= CRIT4FL, dataout=seroconv); %clopper(datain=ADIS, subset= substr(param,1,5) ^= 'LOG10' and &where. , crit= CRIT5FL, dataout=seroresp); %clopper(datain=ADIS, subset=substr(param,1,5) ^= 'LOG10' and &where. , crit= CRIT1FL, dataout=fold2); %clopper(datain=ADIS, subset=substr(param,1,5) ^= 'LOG10' and &where. , crit= CRIT2FL, dataout=fold3); %clopper(datain=ADIS, subset=substr(param,1,5) ^= 'LOG10' and &where. , crit= CRIT3FL, dataout=fold4); proc format; invalue avisitnu "Baseline" = 1 "Day 29" = 5 "Day 43" = 7 "Day 57" = 8 "Day 209" = 9 ; value visit 1 = 'Baseline' 5 = 'Day 29' 7 = 'Day 43' 8 = 'Day 57' 9 = 'Day 209' ; value $param_ "VAC65 Spike IgG Antibody (AU/mL)" = "V65IGGS" ; value $_param_ "V65IGGS" = "VAC65 Spike IgG Antibody (AU/mL)" ; run; ** Apply the format so the pageby_title appears formatted; proc datasets ; modify adis_; format paramcd $_param_.; informat avisitn avisitnu.; run; quit; %macro trt; /* Creates id column using trt variable */ if index(trt,'Placebo') and index(cohort,'Overall') then &_default_trtvar. = 1; else if index(trt,'Placebo') and index(cohort,'>=18') then &_default_trtvar. = 4; else if index(trt,'Placebo') and index(cohort,'>=55') then &_default_trtvar. = 7; else if index(trt,'50') and index(cohort,'Overall') then &_default_trtvar. = 2; else if index(trt,'50') and index(cohort,'>=18') then &_default_trtvar. = 5; else if index(trt,'50') and index(cohort,'>=55') then &_default_trtvar. = 8; else if index(trt,'100') and index(cohort,'Overall') then &_default_trtvar. = 3; else if index(trt,'100') and index(cohort,'>=18') then &_default_trtvar. = 6; else if index(trt,'100') and index(cohort,'>=55') then &_default_trtvar. = 9; else if index(trt,'Total') and index(cohort,'Overall') then &_default_trtvar. = 77; else if index(trt,'Total') and index(cohort,'>=18') then &_default_trtvar. = 88; else if index(trt,'Total') and index(cohort,'>=55') then &_default_trtvar. = 99; avisitn = input(avisit, avisitnu.); %mend; data adis_ci; set adis_ci; %trt run; data seroconv; set seroconv; %trt run; data seroresp; set seroresp; %trt run; /* >= 2-fold Increase */ data fold2; set fold2; %trt run; /* >= 3-fold Increase */ data fold3; set fold3; %trt run; /* >= 4-fold Increase */ data fold4; set fold4; %trt run; ********* !!!!!!!!!!!!!!! MODIFY BELOW WITH CAUTION !!!!!!!!!!!!!! ***************; ***Big N ***; %ma_bign( in_data = &_default_bign_in_data. ,in_where = &_default_bign_in_where ,trigger_bign_in_colhead = YES ,TRIGGER_DUMMY_FOR_ZERO = YES , below_bign = , trigger_split_bign = Y ) *; ** For summary statistics **; %ma_summ_stats ( in_data = adis_ , trtvar = &_default_trtvar. , vars = aval , byvars = paramcd avisitn , BYVARS_PRELOADFMT = $_param_ visit , BYVARS_SORT_ORDER = N N , BYVARS_SORT_ASC_OR_DESC = A A , subgroup = , out_data = SUMM_STATS ); ** Precision **; ** Precision **; %ma_summ_stats_precision ( in_data = adis_ , var = aval , byvars = paramcd , PRECISION_THRESHOLD_ALERT = 16 , out_data = precision_data ) ; data precision_data; set precision_data; if precision >2 then precision = 2; run; ** Rules **; %ma_summ_stats_rules ( in_data = summ_stats , byvars = paramcd , out_data = SUMM_STATS_RULES ) ; ** Display **; %ma_summ_stats_display ( in_data = SUMM_STATS , rules_data = SUMM_STATS_RULES , rules_by = paramcd , precision_data = PRECISION_DATA /* Data set from MA_SUMM_STATS_PRECISION */ , precision_by = paramcd , precision_var = precision , bign_data = bign , in_where = &where. , trtvar = &_default_trtvar. , trtvar_preloadfmt = &_default_display_fmt. , subgroup = , stat_label_fmt = $vstatf. /* the format created with the NOTSORTED option that will create both the label and order */ , na_text = NA /* The text which will be used when the stats are not estimable/not available... */ , separator = &_default_summ_stat_sep. /* the separator used in compound variables like MIN, MAX */ , display = V , out_data = SUMM_DISPLAY , supress_zero_row = N , help = &_default_help , debug = &_default_debug ); data summ_display; set summ_display (drop=_section_); if stat_row = 1 then do; if index(fmtd_avisitn,'Baseline') then stat_label = "n[1]"; else stat_label = "n[3]"; end; if stat_row = 2 then delete; /*delete mean, not needed in this table*/ if stat_row > 2 then stat_row = stat_row + 1; _skipvar_ = byvar2_order; rename byvar1_order=_section_ byvar2_order=_order1_; proc sort; by _section_ paramcd _order1_ avisitn stat_row; run; ** Manipulate ADIS_CI **; proc sql noprint; create table adis_ci0 as select distinct a.*, b.precision from adis_ci a left join precision_data b on a.paramcd = b.paramcd; quit; %macro prec(var=, prec=); length &var._ $50.; length &var._ $50.; if &prec. = 0 then prec = 0.1; if &prec. = 1 then prec = 0.01; if &prec. >= 2 then prec = 0.001; if ~missing(&var.) then do; &var.0=round(&var.,prec); &var._ = strip(put(&var.0, 20.8)); if index(&var._,'.')= 0 then &var._ = strip(&var._)||'.000000000000'; else do; &var._ = strip(put(&var.0, 20.8))||'0000000000'; end; if strip(&var._) ne '' then &var._ = substr(&var._ , 1, index(&var._ , '.' ) + &prec + 1); end; %mend; data adis_ci1 (drop=gmt gmr lowergmt uppergmt lowergmr uppergmr rename=(gmt_=gmt gmr_=gmr lowergmt_=lowergmt uppergmt_=uppergmt lowergmr_=lowergmr uppergmr_=uppergmr)); length gmt_ci gmr_ci $100. paramcd $8.; set adis_ci0; if ~missing(gmt) then do; %prec(var=gmt, prec=1); end; if ~missing(lowergmt) then do; %prec(var=lowergmt, prec=1); end; if ~missing(uppergmt) then do; %prec(var=uppergmt, prec=1); end; gmt_ci = strip(lowergmt_)||", "||strip(uppergmt_); if missing(lowergmt_) or missing (uppergmt_) then gmt_ci = ''; if ~missing(gmr) then do; %prec(var=gmr, prec=1); end; if ~missing(lowergmr) then do; %prec(var=lowergmr, prec=1) ; end; if ~missing(uppergmr) then do; %prec(var=uppergmr, prec=1) end; gmr_ci = strip(lowergmr_)||", "||strip(uppergmr_); if missing(lowergmr_) or missing (uppergmr_) then gmr_ci = ''; run; proc sort data=adis_ci1; by &_default_trtvar paramcd avisitn avisit; run; proc transpose data=adis_ci1 out=ci_transpose1; by &_default_trtvar paramcd avisitn avisit; var gmt gmt_ci gmr gmr_ci; run; data ci_transpose2; set ci_transpose1(rename=(_NAME_=_stat_)); if avisitn=11 and index(_stat_,"GMR") then delete; run; proc sort data=ci_transpose2; by paramcd avisitn avisit _stat_ ; run; proc transpose data=ci_transpose2 out=ci_transpose3 prefix=STAT_VALUE_; by paramcd avisitn avisit _stat_ ; var col1; id &_default_trtvar.; run; ** Finalize CI dataset **; data ci_transpose; length stat_label $70 paramcd $8.; set ci_transpose3(drop=_NAME_); if missing(_order1_) then _order1_ = 1; if upcase(_stat_) = "GMT" then do; stat_label = "GM Level"; stat_row = 2; _indent_ = 4; end; else if upcase(_stat_) = "GMT_CI" then do; stat_label = "95% CI [2]"; stat_row = 3; _indent_ = 4; end; if upcase(_stat_) = "GMR" then do; stat_label = "GM Fold-Rise"; stat_row = 6; _indent_ = 4; end; else if upcase(_stat_) = "GMR_CI" then do; stat_label = "95% CI [2]"; stat_row = 7; _indent_ = 4; end; _order1_ = avisitn; if avisitn = 1 then _skipvar_ = 1; else if avisitn = 5 then _skipvar_ = 2; else if avisitn = 7 then _skipvar_ = 3; else if avisitn = 8 then _skipvar_ = 4; else if avisitn = 9 then _skipvar_ = 5; _section_ = 1; format avisit $avisit. paramcd $_param_.; if avisitn = 1 and stat_row in (6 7) then delete; proc sort; by _section_ paramcd _order1_ avisitn stat_row _SKIPVAR_; run; *** One Row Macro ***; %macro count_row(in_data=adis_, out_data=, inwhere=, intext=, sec=, ord=, ind=, inheader=, hind=2); %ma_count_one_row( in_data = &in_data. ,in_where = &inwhere. ,subgroup = &subgroup. ,text_for_column1 = &intext. ,indent_column1 = &ind. ,_section_ = &sec. ,_order1_ = &ord. ,header = ,HEADER_INDENT = ,out_data = &out_data. , byvars = paramcd avisitn , BYVARS_PRELOADFMT = $_param_ visit , BYVARS_SORT_ORDER = N N , BYVARS_SORT_ASC_OR_DESC = A A ) *; data &out_data.; length col1 $100.; length paramcd $8; set &out_data. ; if index(paramcd,'LV')>0 then delete; _skipvar_ = &ord.; run; data &out_data._header; set &out_data.; _indent_ = 2; _order1_ = &ord - .5; col1 = "&inheader."; keep _section_ avisitn paramcd _skipvar_ _order1_ col1 _indent_ &_default_trtvar; run; proc sort ; by _section_ avisitn paramcd _order1_ col1 _indent_ &_default_trtvar; run; %mend; /*Seroconversion*/ %count_row(out_data=count_sec1, inwhere=index(paramcd,"L10")=0 and CRIT4FL="Y" , intext=%nrstr(n[5] (%%)), inheader=%str(Seroconversion [4]), sec=1, ord=10, ind=4); /*Seroresponse*/ %count_row(out_data=count_sec2, inwhere=index(paramcd,"L10")=0 and CRIT5FL="Y" , intext=%nrstr(n[5] (%%)) , inheader=%str(Seroresponse [7]),sec=2, ord=13, ind=4); /*>=2*/ %count_row(out_data=count_sec3, inwhere=index(upcase(param),"LOG10")=0 and CRIT1FL="Y" , intext=%nrstr(n[5] (%%)), inheader=%str(>=2-fold Increase from Baseline [8]), sec=3, ord=16, ind=4); /*>=3*/ %count_row(out_data=count_sec4, inwhere=index(upcase(param),"LOG10")=0 and CRIT2FL="Y", intext=%nrstr(n[5] (%%)), inheader=%str(>=3-fold Increase from Baseline [8]), sec=4, ord=19, ind=4); /*>=4*/ %count_row(out_data=count_sec5, inwhere=index(upcase(param),"LOG10")=0 and CRIT3FL="Y" , intext=%nrstr(n[5] (%%)), inheader=%str(>=4-fold Increase from Baseline [8]), sec=5, ord=22, ind=4); PROC SQL NOprint; select distinct memname into: count separated by ' ' from dictionary.columns where upcase(libname) = 'WORK' and index(upcase(memname), 'COUNT_') > 0 ; quit; %put Alert_I: &count.; %mu_setall (in_data_list = &count. ,out_data = setall_counts ,trigger_replace_out_data = Y) *; data denom; set SUMM_STATS; if index(fmtd_avisitn,'Baseline')=0 ; denom = var1_n; drop _section_; run; %ma_n_pcnt (in_data = setall_counts ,subgroup = &subgroup ,out_data = N_PCNT ,IN_DENOM_DATA = denom ,IN_DENOM_MERGE_VARS = &_default_trtvar paramcd avisitn ,IN_DENOM_VAR = denom ) *; *** Transpose treatments to columns ***; %mu_transpose( in_data = n_pcnt ,transpose_by = paramcd avisitn _section_ _skipvar_ _order1_ _indent_ col1 ,transpose_vars = n_pcnt ,transpose_id = &_default_trtvar ,out_data = trans ) *; data trans1; set trans; rename N_PCNT_1=STAT_VALUE_1 N_PCNT_2=STAT_VALUE_2 N_PCNT_3=STAT_VALUE_3 N_PCNT_4=STAT_VALUE_4 N_PCNT_5=STAT_VALUE_5 N_PCNT_6=STAT_VALUE_6 N_PCNT_7=STAT_VALUE_7 N_PCNT_8=STAT_VALUE_8 N_PCNT_9=STAT_VALUE_9 N_PCNT_70=STAT_VALUE_70 N_PCNT_80=STAT_VALUE_80 N_PCNT_90=STAT_VALUE_90 N_PCNT_77=STAT_VALUE_77 N_PCNT_88=STAT_VALUE_88 N_PCNT_99=STAT_VALUE_99 COL1=STAT_LABEL; inpnct = 'Y'; stat_row = _order1_; if avisitn = 5 then _order1_=2; if avisitn = 7 then _order1_=3; if avisitn = 8 then _order1_=4; if avisitn = 9 then _order1_=5; if avisitn = 1 or missing(paramcd) then delete; run; ** Manipulate ADIS_CLOP (Seroconv, Seroresp, Fold2, Fold3, Fold4) datasets **; %macro clopper_manip(indata=,outdata=,row1=, row2=, row3=, skip1=, skip2=, skip3=); data &indata.1(drop=lowercl uppercl rename=(lowercl_=lowercl uppercl_=uppercl)); set &indata.; if ~missing(lowercl) then do; %prec(var=lowercl, prec=0) ; end; if ~missing(uppercl) then do; %prec(var=uppercl, prec=0) ; end; cl_ci = strip(lowercl_)||", "||strip(uppercl_); run; proc sort data=&indata.1; by &_default_trtvar paramcd avisitn avisit; run; proc transpose data=&indata.1 out=ci_transp1(rename=(_NAME_=_stat_)); by &_default_trtvar paramcd avisitn avisit; var cl_ci; run; proc sort data=ci_transp1; by paramcd avisitn avisit _stat_; run; proc transpose data=ci_transp1 out=ci_transp2 prefix=STAT_VALUE_; by paramcd avisitn avisit _stat_; var col1; id &_default_trtvar.; run; ** Finalize CI dataset **; data &outdata.; length stat_label $70; set ci_transp2; if upcase(_stat_) = "CL_CI" then do; stat_label = "95% CI [6]"; _indent_ = 4; end; stat_row = 99; if avisitn = 1 then delete; if avisitn = 5 then do; _order1_ = 2; _skipvar_ = &row1.; end; else if avisitn = 7 then do; _order1_ = 3; _skipvar_ = &row1.; end; else if avisitn = 8 then do; _order1_ = 4; _skipvar_ = &row1.; end; else if avisitn = 9 then do; _order1_ = 5; _skipvar_ = &row1.; end; format avisitn visit. paramcd $_param_.; drop _stat_; proc sort; by paramcd _order1_ avisitn stat_row; run; %mend; %clopper_manip(indata=seroconv,outdata=seroconv_trans, row1=10, row2=13, row3=14, skip1=3, skip2=4, skip3=5); %clopper_manip(indata=seroresp,outdata=seroresp_trans, row1=13, row2=15, row3=16, skip1=4, skip2=5, skip3=6); %clopper_manip(indata=fold2,outdata=fold2_trans, row1=16, row2=17, row3=19, skip1=5, skip2=6, skip3=7); %clopper_manip(indata=fold3,outdata=fold3_trans, row1=19, row2=20, row3=22, skip1=6, skip2=7, skip3=8); %clopper_manip(indata=fold4,outdata=fold4_trans, row1=22, row2=23, row3=25, skip1=7, skip2=8, skip3=9); data summ_all_1; set summ_display; proc sort; by _section_ paramcd _order1_ avisitn stat_row; run; ** Add by records before every variable in byvars; %mu_get_sort_order(summ_all_1); %mr_add_by_rec (in_data = summ_all_1 ,sortvars = &sort_order ,byvars = avisitn ,byvarsfmt = visit. ,ordervar = STAT_ROW ,indentspace = 4 ,out_data = DISPLAY ,colname = STAT_LABEL ,help = &_default_help ,debug = &_default_debug ) *; ** Set all summaries **; %mu_setall ( in_data_list = display trans1 ci_transpose seroconv_trans seroresp_trans fold2_trans fold3_trans fold4_trans , out_data = summ_all , trigger_replace_out_data = Y ); proc sort data=summ_all out=summ_all2(drop=fmtd_:); by avisitn _skipvar_ stat_row; run; data display2; length n_STAT_VALUE_1 n_STAT_VALUE_2 n_STAT_VALUE_3 n_STAT_VALUE_4 n_STAT_VALUE_5 n_STAT_VALUE_6 n_STAT_VALUE_7 n_STAT_VALUE_8 n_STAT_VALUE_9 n_STAT_VALUE_70 n_STAT_VALUE_80 n_STAT_VALUE_90 n_STAT_VALUE_77 n_STAT_VALUE_88 n_STAT_VALUE_99 $100; set summ_all2; retain n_STAT_VALUE_1 n_STAT_VALUE_2 n_STAT_VALUE_3 n_STAT_VALUE_4 n_STAT_VALUE_5 n_STAT_VALUE_6 n_STAT_VALUE_7 n_STAT_VALUE_8 n_STAT_VALUE_9 n_STAT_VALUE_70 n_STAT_VALUE_80 n_STAT_VALUE_90 n_STAT_VALUE_77 n_STAT_VALUE_88 n_STAT_VALUE_99; if missing(_skipvar_) then _skipvar_ = _order1_; if stat_label = "" then delete; array n_val {*} n_STAT_VALUE_1 n_STAT_VALUE_2 n_STAT_VALUE_3 n_STAT_VALUE_4 n_STAT_VALUE_5 n_STAT_VALUE_6 n_STAT_VALUE_7 n_STAT_VALUE_8 n_STAT_VALUE_9 n_STAT_VALUE_70 n_STAT_VALUE_80 n_STAT_VALUE_90 n_STAT_VALUE_77 n_STAT_VALUE_88 n_STAT_VALUE_99; array stat_val {*} STAT_VALUE_1 STAT_VALUE_2 STAT_VALUE_3 STAT_VALUE_4 STAT_VALUE_5 STAT_VALUE_6 STAT_VALUE_7 STAT_VALUE_8 STAT_VALUE_9 STAT_VALUE_70 STAT_VALUE_80 STAT_VALUE_90 STAT_VALUE_77 STAT_VALUE_88 STAT_VALUE_99; array len {*} length_1 length_2 length_3 length_4 length_5 length_6 length_7 length_8 length_9 length_70 length_80 length_90 length_77 length_88 length_99; do i = 1 to dim(n_val); len{i} = 18; if length(strip(stat_val{i} )) > len{i} then stat_val{i} = tranwrd(stat_val{i} , ",", ",&_default_escapechar.n")||' '; if index(strip(stat_label),'n[' ) > 0 then do; n_val{i} = strip(stat_val{i}); if index(n_val{i} ,'(')> 0 then n_val{i} = strip(scan(n_val{i} ,1,'(')); end; if index(strip(stat_label),'95%') > 0 then do; *if n_val{i} in ( '0' ) then stat_val{i} = ''; end; end; param = put(paramcd,$_param_.); drop i ; run; proc sort data=display2 out=display3 ; by avisitn _skipvar_ stat_row ; run; %mu_get_sort_order(display3); %if &G_OUTTYPE =INTEXT %then %do; %mw_post_process(indata =display3,column1=stat_label); %end; ** PACKTEXT; %mr_pack ( in_data = display3 , out_data = PACKED , var = stat_label , packvar_label = %str( ) , page_width_chars = &_default_page_width_chars. %if &G_OUTTYPE =INTEXT %then %do; , col1_width_pcnt = 50 %end; %if &G_OUTTYPE ne INTEXT %then %do; , col1_width_pcnt = &_default_col1_width_pcnt %end; , indent = _indent_ , offset = 1 , cont_text = &_default_continued_text. , prcode_split = &_default_prcode_split. , escapechar = &_default_escapechar. ); ** use title and footnote solution to set titles and footnotes; %get_tf(metadata_filepath = &tf_extract. ,tlf_progname = &GET_TF_ID ,escapechar = &_DEFAULT_ESCAPECHAR ,use_parse_char = YES ,write_titles = &_default_write_titles. ,write_footnotes = &_default_write_footnotes. ,out_tf_dataset = YES ,globaltfs = 1 ,Footnote_overline= &_default_Footnote_overline. ,Footnote_hanging_indent = &_default_hanging_indent %if &G_OUTTYPE ne INTEXT %then %do; ,fpage = Yes ,fpage_first_footnote = %str(Notes are listed on last page.) %end; )*; %if &G_OUTTYPE. ne %str(INTEXT) %then %do; ** this macro uses the dataset produced by get_tf ** if using spanning headers and/or subgroup titles, enter the total ** number of these extra lines into SPANNER_SUBGROUP_LINES; %mu_lines_per_page (tlf_progname = &get_tf_id. ,spanner_lines = 1 ,linesperpage = %sysevalf(&_default_page_length_lines.) ,in_data = PACKED ,escapechar = &_default_escapechar. ,prcode_split = &_default_prcode_split. ,rtfwidth = &_default_page_width_chars. ,debug = &_default_debug ,headerlines = 2 ); ** decimal align the columns; *Decimal align for overall group; %mu_align ( in_data = PACKED , out_data = prefinal , align = C , left_spacing = 1100 , columns = STAT_VALUE_1 STAT_VALUE_2 STAT_VALUE_3 STAT_VALUE_77 STAT_VALUE_70 ); *Center align for cohorts; %mu_align ( in_data = prefinal , out_data = final1 , align = C , left_spacing = 450 , columns = STAT_VALUE_4 STAT_VALUE_5 STAT_VALUE_6 STAT_VALUE_88 STAT_VALUE_80 STAT_VALUE_7 STAT_VALUE_8 STAT_VALUE_9 STAT_VALUE_99 STAT_VALUE_90 ); data final; set final1(drop= length: _stat_ _subord_ n_stat: _name_); if avisitn = 1 then pagenum = 1; else if avisitn = 5 and _skipvar_ not in (19 22)then pagenum = 2; else if avisitn = 5 and _skipvar_ in (19 22) then pagenum = 3; else if avisitn not in (1 5) and _skipvar_ not in (19 22) then pagenum = 2*(avisitn - 4)-2; else if avisitn not in (1 5) and _skipvar_ in (19 22) then pagenum = 2*(avisitn - 4)-1; if stat_row = 99 then stat_row = _skipvar_+0.5 ; /* Fix value for sorting */ _section_ = 1; _order1_ = avisitn; _order2_ = stat_row; _order3_ = _skipvar_; array CI {*} STAT_VALUE_4 STAT_VALUE_5 STAT_VALUE_6 STAT_VALUE_7 STAT_VALUE_8 STAT_VALUE_9 STAT_VALUE_70 STAT_VALUE_80 STAT_VALUE_90 STAT_VALUE_88 STAT_VALUE_99; do k = 1 to dim(CI); if index(stat_label,'CI') or index(stat_label,',') then CI{k} = tranwrd(CI{k},", ",",&_default_escapechar.n"); end; proc sort; by pagenum _order1_ _order2_ _order3_ _section_ ; run; %mu_get_sort_order(final); proc sql noprint; select subtitle into: param from subgroup; quit; *** Generate Report ***; %macro bygroup(indata=, section=, param=); data %sysfunc(compress(indata§ion)); set &indata.; if _section_ = §ion.; run; %let _default_report_options = nowd missing spacing=1 split="&_default_prcode_split" ; %table_report(type=A, in_data=%sysfunc(compress(indata§ion)), column_1=pack_stat_label, col1_label=&_default_col1_label., _order2_=_order2_, _order3_=_order3_, colprefix = STAT_VALUE, Trig_disp=N); TITLE6 justify=left "&_default_escapechar.n¶m."; data processed1; set processed1(drop=pagenum); if _skipvar_ in (19 22) then _section_ = _order1_ + 0.5; else _section_ = _order1_; _skipvar_ = 100*_order1_ + _skipvar_; proc sort; by _section_ _skipvar_ _order1_ _order2_ _order3_; run; data processed2; set processed2(drop=pagenum); if _skipvar_ in (19 22) then _section_ = _order1_ + 0.5; else _section_ = _order1_; _skipvar_ = 100*_order1_ + _skipvar_; proc sort; by _section_ _skipvar_ _order1_ _order2_ _order3_; run; %mr_pagebreak_table (vartx = pack_stat_label STAT_VALUE_1 STAT_VALUE_2 STAT_VALUE_3 STAT_VALUE_77 ,lines_left_on_page = %eval(&g_linesleft.+6) ,in_data = processed1 ,out_data = processed100 ,escapechar = &_default_escapechar. ,subgrp = _section_ ,orderby = _section_ _skipvar_ _order1_ _order2_ ,section = _skipvar_ ,lineskip = 0 ,section_protection = Y ); %mr_pagebreak_table (vartx = pack_stat_label STAT_VALUE_4 STAT_VALUE_5 STAT_VALUE_6 STAT_VALUE_88 STAT_VALUE_7 STAT_VALUE_8 STAT_VALUE_9 STAT_VALUE_99 ,lines_left_on_page = %eval(&g_linesleft.+6) ,in_data = processed2 ,out_data = processed200 ,escapechar = &_default_escapechar. ,subgrp = _section_ ,orderby = _section_ _skipvar_ _order1_ _order2_ ,section = _skipvar_ ,lineskip = 0 ,section_protection = Y ); %ml_report(in_data = processed100, META_DATA = meta_data1, pagenum = pagenum, debug = y, NO_OBS_LINE= &_DEFAULT_NO_SUBJECTS_TABLE.) *; %ml_report(in_data = processed200, META_DATA = meta_data2, pagenum = pagenum, debug = y, NO_OBS_LINE= &_DEFAULT_NO_SUBJECTS_TABLE.) *; proc datasets lib=work nolist; delete meta_data1 meta_data2; run; %mend; *** Open ODS ***; %mr_odsout *; data _null_; set subgroup; call execute('%nrstr( %bygroup( indata=FINAL, section='||strip(put(N, best.))||', param='||strip(subtitle)||' ); )'); run; %get_tf (metadata_filepath = &tf_extract. ,tlf_progname = &GET_TF_ID ,escapechar = &_DEFAULT_ESCAPECHAR ,use_parse_char = YES ,write_titles = yes ,write_footnotes = yes ,out_tf_dataset = YES ,globaltfs = 1 ,fpage = Yes ,fpage_first_footnote = %str(Notes are listed on last page.) )*; *** Close ODS ***; %mr_odsclose *; %end; /*________________________________________________________________*/ %else %do; proc sort data=packed; by avisitn _skipvar_ stat_row _section_ _order1_ ; run; %mu_get_sort_order(packed); %let _default_col1_width_pcnt = 12; %let _DEFAULT_PAGE_LENGTH_LINES = 44; proc sql noprint; select subtitle into: param from subgroup; quit; data PACK; length param $100.; set packed ; pagenum = 1; array nstrip {*} n_STAT_VALUE_1 n_STAT_VALUE_2 n_STAT_VALUE_3 n_STAT_VALUE_4 n_STAT_VALUE_5 n_STAT_VALUE_6 n_STAT_VALUE_7 n_STAT_VALUE_8 n_STAT_VALUE_9 n_STAT_VALUE_70 n_STAT_VALUE_80 n_STAT_VALUE_90 n_STAT_VALUE_77 n_STAT_VALUE_88 n_STAT_VALUE_99; do i = 1 to dim(nstrip); nstrip{i} =strip(nstrip{i}); end; array stat_val {*} STAT_VALUE_1 STAT_VALUE_2 STAT_VALUE_3 STAT_VALUE_4 STAT_VALUE_5 STAT_VALUE_6 STAT_VALUE_7 STAT_VALUE_8 STAT_VALUE_9 STAT_VALUE_70 STAT_VALUE_80 STAT_VALUE_90 STAT_VALUE_77 STAT_VALUE_88 STAT_VALUE_99; do i = 1 to dim(stat_val); stat_val{i} = strip(stat_val{i}); end; param = "¶m."; param = compbl( tranwrd(param, "&_default_escapechar.n",'') ); param = compbl( tranwrd(param, "Nucleocapsid IgG Antibody",'nucleocapsid IgG antibody') ); param = compbl( tranwrd(param, "Antibody",'antibody') ); param = compbl( tranwrd(param, "Spike",'spike') ); param = compbl( tranwrd(param, "MN Endpoint Titer",'MN endpoint titer') ); param = compbl( tranwrd(param, "antibody: ",'Antibody: ') ); pack_stat_label = tranwrd(pack_stat_label,'day','Day'); pack_col1 = tranwrd(pack_stat_label,'^n',''); _order1_ = avisitn; _order2_ = _skipvar_; _order3_ = stat_row; _section_ = 1; proc sort; by _order1_ _order2_ _order3_ _section_ ; run; run; data &GET_TF_ID._TF_1; set &GET_TF_ID._TF; _tftext1=tranwrd(_tftext1, "escapechar", "_default_escapechar"); _tftext1=tranwrd(strip(_tftext1),"'a0'x","||'a0'x"); put _tftext1=; run; proc sql noprint ; select _tftext1 into :footnotes separated by "|| '&_default_escapechar.n' ||" from &GET_TF_ID._TF_1 where _TorF eqt 'F' order by _seq ; quit ; %mr_odsout ( escapechar = &_default_escapechar , style = &_default_template_style , filecase = &_default_filecase , deliverableid = &g_deliverableid , options= &_default_ods_options. , idcompress = ); ***OVERALL subgroup***; proc report data=PACK missing split="$" nowd style(report)={outputwidth = 100%} ; COLUMNS pagenum _section_ param _order1_ _skipvar_ _order2_ _order3_ pack_col1 ( "&_default_escapechar.R/RTF'\brdrb\brdrs\li100\ri100' Overall &_default_escapechar. " STAT_VALUE_1 ( "&_default_escapechar.R/RTF'\brdrb\brdrs\li100\ri100' mRNA-1273 &_default_escapechar. " STAT_VALUE_2 STAT_VALUE_3 STAT_VALUE_77 )) ; define PAGENUM / "PAGENUM" ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; define _section_ /ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; define param / ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; compute before param / style=[just=L font_weight=bold]; line param $200.; endcomp; define _order1_/ ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; define _skipvar_/ ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; compute after _skipvar_/ style={cellheight=1 ex}; line " "; endcomp; define _order2_ / ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; define _order3_ / ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; define pack_col1 / "&_default_col1_label." style(column)=[cellwidth=12% asis=on] style(header)=[just=l asis=on]; define STAT_VALUE_1 / "&colhead_1" style(column)=[cellwidth=10% asis=on vjust=b just=c protectspecialchars=off]; define STAT_VALUE_2 / "&colhead_2" style(column)=[cellwidth=10% asis=on vjust=b just=c protectspecialchars=off]; define STAT_VALUE_3 / "&colhead_3" style(column)=[cellwidth=10% asis=on vjust=b just=c protectspecialchars=off]; define STAT_VALUE_77/ "&colhead_77" style(column)=[cellwidth=10% asis=on vjust=b just=c protectspecialchars=off]; define pagenum / order order=internal noprint; compute before pagenum /style={cellheight=1ex}; line " "; endcomp; break after pagenum / page; run; data _null_; length g_footer $1000.; g_footer=strip(symget('g_footer')); call execute('footnote'||"%eval(&footnote_count+1)"||' j=L"'||strip(g_footer)||strip('";')); run; title; proc report data=PACK missing split="$" nowd style(report)={outputwidth = 100%} ; COLUMNS pagenum _section_ param _order1_ _skipvar_ _order2_ _order3_ pack_col1 ("Cohort 1 (Age >= 18 and age < 55) &_default_escapechar.R/RTF'\brdrb\brdrs\li100\ri100'" STAT_VALUE_4 ( "&_default_escapechar.R/RTF'\brdrb\brdrs\li100\ri100' mRNA-1273 &_default_escapechar. " STAT_VALUE_5 STAT_VALUE_6 STAT_VALUE_88) ) ("Cohort 2 (Age >= 55) &_default_escapechar.R/RTF'\brdrb\brdrs\li100\ri100'" STAT_VALUE_7 ( "&_default_escapechar.R/RTF'\brdrb\brdrs\li100\ri100' mRNA-1273 &_default_escapechar. " STAT_VALUE_8 STAT_VALUE_9 STAT_VALUE_99) ); define PAGENUM / "PAGENUM" ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; define _section_ /ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; define param / ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; compute before param / style=[just=L font_weight=bold]; line param $200.; endcomp; define _order1_/ ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; define _skipvar_/ ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; compute after _skipvar_/ style={cellheight=0.5 ex}; line " "; endcomp; define _order2_ / ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; define _order3_ / ORDER NOPRINT ORDER=INTERNAL ID style(header)={just=c vjust=m asis=on ProtectSpecialChars=off just=c } style(column)={just=l vjust=t asis=on ProtectSpecialChars=off ProtectSpecialChars=OFF asis = ON JUST=C cellwidth=0%} ; define pack_col1 / "&_default_col1_label." style(column)=[cellwidth=10% asis=on] style(header)=[just=l asis=on]; define STAT_VALUE_4 / "&colhead_4" style(column)=[cellwidth=6% asis=on vjust=b just=c protectspecialchars=off]; define STAT_VALUE_5 / "&colhead_5" style(column)=[cellwidth=6% asis=on vjust=b just=c protectspecialchars=off]; define STAT_VALUE_6 / "&colhead_6" style(column)=[cellwidth=6% asis=on vjust=b just=c protectspecialchars=off]; define STAT_VALUE_88/ "&colhead_88" style(column)=[cellwidth=6% asis=on vjust=b just=c protectspecialchars=off]; define STAT_VALUE_7 / "&colhead_7" style(column)=[cellwidth=6% asis=on vjust=b just=c protectspecialchars=off]; define STAT_VALUE_8 / "&colhead_8" style(column)=[cellwidth=6% asis=on vjust=b just=c protectspecialchars=off]; define STAT_VALUE_9 / "&colhead_9" style(column)=[cellwidth=6% asis=on vjust=b just=c protectspecialchars=off]; define STAT_VALUE_99/ "&colhead_99" style(column)=[cellwidth=6% asis=on vjust=b just=c protectspecialchars=off]; define pagenum / order order=internal noprint; compute before pagenum /style={cellheight=1ex}; line " "; endcomp; break after pagenum / page; compute after pagenum / style=[just=L asis=on]; if (pagenum = 1) or ("" ne "") then do; length txt $5000.; txt=tranwrd(&footnotes.," ;",";"); line txt $5000.; end; endcomp; run; * close ODS; %mr_odsclose *; %end;