SAS编程宏处理1--描述性统计量的输出

2021-03-23  本文已影响0人  野藤_

宏程序在我们日常编程中被普遍使用。项目中的很多输出内容都是相同的标准和模板,如果每次都手动编写程序,这样的效率未免有些低下。我写宏程序这系列文章的目的,就是将工作中可能遇到的宏程序积累下来,以方便下次调用。这一系列要写多少以及怎么写,我自己也不太确定,就先开始写起来。

相同的输出可以通过不同的程序来实现,与之对应的宏程序的实现也并非固定。我先尽量为每种输出形式完成一种形式,至于丰富实现方法,以后再补充。文章的框架是先以普通的SAS程序实现输出,最后将程序封装成宏程序,方便使用。

我先介绍输出描述性统计量的宏程序。描述性统计量的输出在临床试验统计分析中非常普遍,每一个临床试验的SAP中都应该有类似的语句:

Descriptive statistics on continuous measurements will include means, medians, standard deviations, quartiles(Q1, Q3) and minimum and maximum, while categorical data will be summarized using frequency counts and percentages.

至于如何实现描述性统计量的输出,从我接触的项目中来看,大致有3种实现途径:

  1. Proc Means
  2. Proc Univariate
  3. Proc Summary

今天我来介绍Proc Summary的实现方法,我以SASHELP.CLASS数据集作为分析数据集,输出不同性别同学的身高的描述性统计量。首先,我们先看一下描述性统计量的模板,关于模板各个公司应该大同小异:

描述性统计量

我这边就不介绍具体的SAS语法了,直接看程序如何实现:

proc summary data = sashelp.class;
  class sex;
  var height;
  output out=height1 n=n mean=mean median=median std=std min=min max=max q1=q1 q3=q3;
run;

以上代码将各分组以及分组汇总的统计量输出到Height1数据集中:


Height1

描述性统计量获取后,需要整理成模板显示的形式。显然,模板显示的竖向排列,而输出的数据集中是横向排列的。这里实现的方法一般有两种,第一,Proc Tranpose语句将横向数据转变为纵向数据;第二,在Data步中使用Ouput语句实现纵向输出。

这里,我采用Proc Tranpose进行实现。关于各个统计量的保留的小数位数,不同的公司可能有不同的要求,在这里min、max先保留一位,mean、std、q1、q3先保留两位。小数位数在最后的宏程序中可以使用宏参数进行控制。

data height2;
  set height1;
  where not missing(sex);
  length v1-v6 $50;

  if n >. then v1=strip(put(n, 4.0)); else v1 = "0";
  if mean >. then v2=strip(put(mean,8.2)); else v2="-";
  if std>. then v3=strip(put(std,8.2)); else v3="-";
  if median>. then v4=strip(put(median,8.2)); else v4="-";
  if nmiss(q1,q3) =0 then v5=strip(put(q1,8.2))||", "||strip(put(q3,8.2)); else v5="-, -";
  if nmiss(min,max) =0 then v6=strip(put(min,8.1))||", "||strip(put(max,8.1)); else v6="-, -";
run;

proc transpose data = height2 out=height3;
  var v1 -v6;
run;

输出结果如下:


Height2 Height3

这里输出的整体内容已经很完善了,但是第一列没有具体统计量名称,需要进一步补充,这里可以通过建立Format进行实现。

proc format;
  value $stat
    "v1" = "n"
    "v2" = "Mean"
    "v3" = "SD"
    "v4" = "Median"
    "v5" = "Q1, Q3"
    "v6" = "Min, Max"
  ;
run;

data out;
  set height3;
  _name_ = put(_name_, $stat.);
run;

Out

以上就是整个输出描述性统计量的过程,这是一个整体的框架,一些细节可能不同公司有不同要求,具体细节读者可以自行补充。考虑到一张Table可能出多个变量的描述性统计量,可以添加一个变量记录表属于具体的表的第几部分,也可以增加记录同一部分中的统计量排列顺序的变量。

将以上程序封装成宏程序,具体如下:

%macro Summary(indt=, outdt=, trtvar=, anavar=, dplace=, sec=);
proc summary data = &indt.;
  class &trtvar.;
  var &anavar.;
  output out=&anavar.1 n=n mean=mean median=median std=std min=min max=max q1=q1 q3=q3;
run;

data &anavar.2;
  set &anavar.1;
  where not missing(&trtvar.);
  length v1-v6 $50;

  %let dplace1 = %eval(&dplace. +1);  

  if n >. then v1=strip(put(n, 4.0)); else v1 = "0";
  if mean >. then v2=strip(put(mean,8.&dplace1.)); else v2="-";
  if std>. then v3=strip(put(std,8.&dplace1.)); else v3="-";
  if median>. then v4=strip(put(median,8.&dplace1.)); else v4="-";
  if nmiss(q1,q3) =0 then v5=strip(put(q1,8.&dplace1.))||", "||strip(put(q3,8.&dplace1.)); else v5="-, -";
  if nmiss(min,max) =0 then v6=strip(put(min,8.&dplace.))||", "||strip(put(max,8.&dplace.)); else v6="-, -";
run;

proc transpose data = &anavar.2 out=&anavar.3;
  var v1 -v6;
run;

data &outdt;
  set &anavar.3;
  _name_ = put(_name_, $stat.);
  sec = &sec.;
  rownum=_n_;
run;
%mend;

%Summary(indt=sashelp.class, outdt=out, trtvar=sex, anavar=height, dplace=1, sec=1);

输出结果如下:


Out

以上。
若有疑问,欢迎评论区交流!

上一篇下一篇

猜你喜欢

热点阅读