<p>薛博士的宏程序确实不错,但尚不能自动生成我们需要的统计表格,以下这段代码是我在薛博士的基础上,经过一个下午的时间编写出来的,运行后可以自动生成标准的统计表格(配合ODS),如果版主认为还行的话,请奖励一些论坛币(我很穷啊),谢谢!</p><p>程序在sas9.0英文版中运行通过。</p><p>%macro comdts(j,k,dataname); <br/> %do i=&j %to &k; <br/> &dataname&i <br/> %end; <br/> %mend comdts; <br/></p><p>%macro comparison(data=,vars=,vg1=,vg2=,vg3=,vg4=,class=,par=1,format=6.1,total=1,where=);<br/>/*扫描宏参数中包含的应变量名称,并将其赋值给一系列宏变量*/<br/>ods select none;<br/>%let i=1;<br/>%do %while(%scan(&vars,&i) ne );%let var&i=%scan(&vars,&i);%let i=%eval(&i+1);%end;<br/>/*获取应变量个数*/<br/>%let vnum=%eval(&i-1);<br/>/*获取指定分组变量的水平数*/<br/>proc freq data=&data;tables &class/out=freout;run;<br/>data _null_;set freout end=last;if last then call symput('lvnum',compress(_n_));<br/>run;<br/>/*分组变量水平数小于2时给出警告信息,并跳出宏运行进程*/<br/>%if &lvnum<2 %then %do;<br/> %put Warning: Level number of class variable is less than 2.;<br/> %goto exitmacro;<br/>%end;</p><p>/*数据描述*/<br/>%do i=1 %to &vnum;<br/> proc means data=&data n nmiss mean std min max lclm uclm median maxdec=2;<br/> output out=tmpmean&i n=n nmiss=nmiss mean=mean std=std min=min max=max lclm=lclm uclm=uclm <br/> median=median;class &class; %if &where ne %then %do;where &where;%end;<br/> var &&var&i;<br/> run;</p><p> data tmpmean&i;set tmpmean&i;<br/> nnmiss=compress(put(n,6.0)||"("||left(put(nmiss,6.0))||")");<br/> ms=put(mean,&format)||"+"||left(put(std,&format));<br/> minax=put(min,&format)||"~"||left(put(max,&format));<br/> luclm=put(lclm,&format)||"~"||left(put(uclm,&format));<br/> med=put(median,&format);<br/> run;</p><p> %if &lvnum=2 %then %do;</p><p> /* t-test */;<br/> %if &par=1 %then %do;<br/> ods output ttests=ttests equality=equality;<br/> proc ttest data=&data;var &&var&i;class &class;<br/> %if &where ne %then %do;where &where;%end;<br/> data test2;merge ttests equality;by variable;<br/> data test21;set test2;where probf>0.05 and variances='Equal';length stat $ 5; stat="";<br/> data test22;set test2;where probf<0.05 and variances='Unequal';length stat $ 5;stat="*";<br/> data test(keep=variable pvalue);merge test21 test22;<br/> length variable $10.;variable="&&var&i.";<br/> pvalue=left(put(probt,6.3))||stat;<br/> run;<br/> %end;<br/> /*秩和检验*/;<br/> %if &par^=1 %then %do;<br/> proc npar1way wilcoxon data=&data;<br/> %if &where ne %then %do;where &where;%end;<br/> ods output kruskalwallistest=tmp1;var &&var&i;class &class;run;<br/> data test(keep=variable pvalue);set tmp1(rename=nvalue1=p);<br/> where label1='Pr > Chi-Square';methods='**';<br/> pvalue=left(put(p,6.3))||methods;length variable $10.;variable="&&var&i.";run;<br/> %end;<br/>/*描述数据*/;<br/>/*给出两组之合计值*/;<br/> %if &total=1 %then %do;<br/> proc iml;reset noname linesize=100;<br/> use tmpmean&i;setin tmpmean&i;<br/> read all var {nnmiss ms minax luclm med} where(&class=&vg1) into nn1;<br/> read all var {nnmiss ms minax luclm med} where(&class=&vg2) into nn2;<br/> read all var {nnmiss ms minax luclm med} where(&class=.) into nn;<br/> nn11=nn1`;nn12=nn2`;nnt=nn`;<br/> aaa=nn11||nn12||nnt;bbb={"N(miss)","Mean+SD","Min~Max","95% CI(L~U)","Median"};<br/> ab=bbb||aaa;create mydata&i from ab;append from ab;quit;<br/> %end;<br/> data mydata1&i;merge test mydata&i;run;<br/> data mydata1&i;retain variable col1 col2 col3 col4 pvalue;set mydata1&i;<br/> run;<br/>/*不给出两组之合计值*/;</p><p> %if &total^=1 %then %do;<br/> proc iml;reset noname linesize=100;<br/> use tmpmean&i;setin tmpmean&i;<br/> read all var {nnmiss ms minax luclm med} where(&class=&vg1) into nn1;<br/> read all var {nnmiss ms minax luclm med} where(&class=&vg2) into nn2;<br/> nn11=nn1`;nn12=nn2`;<br/> aaa=nn11||nn12;bbb={"N(miss)","Mean+SD","Min~Max","95% CI(L~U)","Median"};<br/> ab=bbb||aaa;create mydata&i from ab;append from ab;quit;<br/> %end;<br/> data mydata1&i;merge test mydata&i;run;<br/> data mydata1&i;retain variable col1 col2 col3 pvalue;set mydata1&i;<br/> run;<br/> %end;</p><p> %if &lvnum>2 %then %do;</p><p>/* ANOVA test */;<br/> %if &par=1 %then %do;<br/> proc glm data=&data;class &class;model &&var&i=&class;<br/> ods output overallanova=tmpanova diff=tmpf(rename=(_1=t12 _2=t13 _3=t23 p1=p12 p2=p13 p3=p23));<br/> lsmeans &class/tdiff pdiff;%if &where ne %then %do;where &where;%end;<br/> run;</p><p> data t12(keep=pvalue);set tmpf;if _n_=1;rename t13=t1;<br/> p1=left(put(p13,6.3));pvalue=p1||'*';*Group1:group2;<br/> run;<br/> data t13(keep=pvalue);set tmpf;if _n_=1;rename t23=t2;<br/> p2=left(put(p23,6.3));pvalue=p2||'**';*Group1:Group3;<br/> run;<br/> data t23(keep=pvalue);set tmpf;if _n_=2;rename t23=t3;<br/> p3=left(put(p23,6.3));pvalue=p3||'***';*Group2:Group3;<br/> run;<br/> data tmpanova(keep=variable pvalue);set tmpanova;if _n_=1;<br/> length variable $10.;variable="&&var&i.";length pvalue $10.;<br/> pvalue=left(put(probf,6.3));run;<br/> data test;set tmpanova t12 t13 t23;run;<br/> %end;</p><p>/*秩和检验*/;<br/> %if &par^=1 %then %do;<br/> proc npar1way wilcoxon data=&data;%if &where ne %then %do;where &where;%end;<br/> ods output kruskalwallistest=tmp1;var &&var&i;class &class;run;</p><p> data test(keep=variable pvalue);set tmp1(rename=nvalue1=p);<br/> where label1='Pr > Chi-Square';methods='**';<br/> pvalue=left(put(p,6.3))||methods;length variable $10.;variable="&&var&i.";run;<br/> %end;</p><p>/*描述数据*/;<br/>/*给出三组的合计值*/;<br/> %if &total=1 %then %do;<br/> proc iml;reset noname linesize=100;<br/> use tmpmean&i;setin tmpmean&i;<br/> read all var {nnmiss ms minax luclm med} where(&class=&vg1) into nn1;<br/> read all var {nnmiss ms minax luclm med} where(&class=&vg2) into nn2;<br/> read all var {nnmiss ms minax luclm med} where(&class=&vg3) into nn3;<br/> read all var {nnmiss ms minax luclm med} where(&class=.) into nn;<br/> nn11=nn1`;nn12=nn2`;nn13=nn3`;nnt=nn`;<br/> aaa=nn11||nn12||nn13||nnt;bbb={"N(miss)","Mean+SD","Min~Max","95% CI(L~U)","Median"};<br/> ab=bbb||aaa;create mydata&i from ab;append from ab;quit;<br/> %end;<br/> data mydata1&i;merge test mydata&i;run;<br/> data mydata1&i;retain variable col1 col2 col3 col4 col5 pvalue;set mydata1&i;<br/> run;</p><p>/*不给三组的合计值*/;<br/> %if &total^=1 %then %do;<br/> proc iml;reset noname linesize=100;<br/> use tmpmean&i;setin tmpmean&i;<br/> read all var {nnmiss ms minax luclm med} where(&class=&vg1) into nn1;<br/> read all var {nnmiss ms minax luclm med} where(&class=&vg2) into nn2;<br/> read all var {nnmiss ms minax luclm med} where(&class=&vg3) into nn3;<br/> nn11=nn1`;nn12=nn2`;nn13=nn3`;<br/> aaa=nn11||nn12||nn13;bbb={"N(miss)","Mean+SD","Min~Max","95% CI(L~U)","Median"};<br/> ab=bbb||aaa;create mydata&i from ab;append from ab;quit;<br/> %end;</p><p> data mydata1&i;merge test mydata&i;run;<br/> data mydata1&i;retain variable col1 col2 col3 col4 pvalue;set mydata1&i;<br/> run; <br/>%end;%end;<br/>data mydata;set %comdts(1,&vnum,mydata1); <br/>ods select all;<br/>proc print data=mydata noobs;run;<br/>%exitmacro:<br/>%mend comparison;<br/>*应用举例:%comparison(data=aaa,vars=height weight age hcy1 sbp1 dbp1 sbp2 dbp2 sbp4 dbp4<br/>,vg1=1,vg2=2,class=sex,par=1,format=6.1,total=1);<br/>*%comparison(data=aaa,vars=age hcy1 hcy4 hcy8 sbp1 dbp1 sbp2 dbp2 weight height,vg1=1,vg2=2,<br/>vg3=3(分组变量的值),class=group,par=1(参数检验),format=6.1,total=1(有合计值));<br/></p><p></p>