Creating a neat and reader-friendly SAS t-test report

The following SAS macro is for creating a neat and reader-friendly t-test report. The primary goal of this code is to make the t-test report easy to read for every person. The secondary goal is to reduce statisticians' workload. The macro has the ability to run multiple t-tests at a time, which can simplify SAS code greatly. If you have any problem with running this macro, please leave your comment to let me know.

Example code:

data example;
set SASHELP.applianc;
if MOD(cycle,2)=1 then Group="A";
else Group="B";
keep units_1-units_6 group;
run;

proc print data=example(obs=8);
run;

%INCLUDE "/folders/myshortcuts/SASfolder/Tools/MacroTTest.sas";
%MacroTTest(table=example,var=units_1 units_2 units_3 units_4 units_5 units_6,Byvar=Group);

Result:


Macro:


%MACRO MacroTTest_hiden(table=,var=,Byvar=,title=0,alpha=);
/*Change a given variable to character*/
%INCLUDE "/folders/myshortcuts/SASfolder/Tools/NumToStr.sas" ;
%Num2Str(table=&table,var=&Byvar,newTable=TempData);

proc sort data=TempData out=temp1 nodupkey;
by &Byvar;
run;

data temp1;
set temp1;
length n $10.;
n=put(_n_,10.);
where not missing(&Byvar);
run;

proc sql noprint;
        select 
        "if "||"&Byvar= '"||&Byvar||"'"|| " then "||compress("&Byvar='level"||n||"'")||";"
        into:ChangeLevel separated by ' '
                from temp1;
        select  "label "||compress("level"||n)||"="||'"'||&Byvar||'(MEAN& SD)"'
        into:LevelNote separated by ';'
                from temp1;
        select  compress("MEANlevel"||n)
        into:MEANList separated by ' '
                from temp1;       
        select  compress("STDlevel"||n)
        into:STDList separated by ' '
                from temp1;
        select compress("level"||n)
        into:NewLevelList separated by ' '
                from temp1;            

quit;

data TempData;
set TempData;
&ChangeLevel;
run;


proc means data=TempData mean STDDEV noprint;
var &var; 
class &Byvar ;
OUTPUT out=summaryTable;
run;
data summaryTable;
set summaryTable;
where (_Stat_="STD" or _Stat_="MEAN") and &Byvar  is not missing;
drop _type_ _freq_;
run;



proc transpose data=summaryTable out=summaryTable ;
   id _STAT_ &Byvar  ;
run;

data summaryTable ;
set summaryTable ;
array x[*] &MEANList &STDList;
array y[*] $20. &NewLevelList;
do i=1 to dim(y);
y[i]=compress(strip(put(x[i],10.2)||"("||put(x[i+dim(y)],10.2)||")"));
end;
rename _NAME_=var;
run;
data summaryTable;
set summaryTable;
keep &NewLevelList var;
run;



/*===========================*/
ods select none;
ods output TTests=ANOVAP;
proc ttest data=TempData;
   var &var;
   class &Byvar;
run;
ods output close;
ods select all;
data ANOVAP;
set ANOVAP;
rename Variable=var;

run;

data ANOVAP;
set ANOVAP;
where Method='Satterthwaite';
keep var tValue DF Probt;
run;

proc sort data=summaryTable out=summaryTable;
by var;
run;
proc sort data=ANOVAP out=ANOVAP;
by var;
run;

data summaryTableP;
merge summaryTable ANOVAP;
by var;
run;

data summaryTableP;
set summaryTableP;
significant=" ";
if Probt<&alpha and not missing(Probt) then significant="*";
run;

%if &title=2 %then %do;
data summaryTableP;
set summaryTableP;
length tempvar $20.;
tempvar="&byvar";
drop var;
run;
data summaryTableP;
set summaryTableP;
rename tempvar=var;
run;
%end;


data summaryTableP;
retain var;
set summaryTableP;
run;

/*Sorting variable to keep them in the same order as the order in macro*/
data summaryTableP;
set summaryTableP;
%let aryLength_TTest_hidden=%sysfunc(COUNTW(&var,' '));
%do hidden_i = 1 %to &aryLength_TTest_hidden;
if var="%sysfunc(SCAN(&var,&hidden_i,' '))" then index= &hidden_i;
%end
run;
proc sort data=summaryTableP;
by index;
run;
data summaryTableP;
set summaryTableP;
drop index;
run;



/*===========Print Table=============*/
%if &title=0 %then %do;
title10 "T-Test for continuous variables across variable &Byvar";
footnote10"*P-value is given by the t test based on the unequal variance assumption.";

proc print data=summaryTableP label;
label var='var';
&LevelNote;
label Probt='Pr>F*';
run;
footnote;
title0;
%end;
%MEND MacroTTest_hiden;


%macro MacroTTest(table=,var=,Byvar=,alpha=0.05);

%let aryLength_TTest=%sysfunc(COUNTW(&Byvar,' '));
%put The array length is: &aryLength_TTest;
%if &aryLength_TTest=1 %then %MacroTTest_hiden(table=&table,var=&var,Byvar=&Byvar,alpha=&alpha);
%else %do;
/*If has multiple Byvar*/


%MacroTTest_hiden(table=&table,var=&var,Byvar=%sysfunc(SCAN(&Byvar,1,' ')),title=2,alpha=&alpha);
data summaryTableP;
set summaryTableP;
keep var Probt tvalue significant;
run;
data summaryTableP1;
set summaryTableP;
run;



%Do varIndex=2 %To &aryLength_TTest ;
*%put Current is &varIndex||&aryLength_TTest;
%MacroTTest_hiden(table=&table,var=&var,Byvar=%sysfunc(SCAN(&Byvar,&varIndex,' ')),title=2,alpha=&alpha);
data summaryTableP;
set summaryTableP;
keep var Probt tvalue significant;
run;
data summaryTableP1;
set summaryTableP1 summaryTableP;
run;
%put Current is &varIndex||&aryLength_TTest;
%End;

title10 "T-Test for discrete variables across variable &var";
footnote10"*P-value is given by the t test based on the unequal variance assumption.";

proc print data=summaryTableP1 label;
label var='var';
label Probt='Pr>F*';
run;
footnote;
title0;
/*===========Print Table=============*/
%end;

%Mend MacroTTest;

Comments

Popular posts from this blog

Creating a neat and reader-friendly SAS ANOVA report