SAS編程實(shí)踐---宏:從頭手搓一個(gè)生成”基本描述性統(tǒng)計(jì)量表格“的宏

寫在前面第美。

最近的兩篇文章分別介紹了我編寫下面這兩個(gè)宏時(shí)整體的思路和方法增显。菜鳥小白一枚,很歡迎有大佬能夠閱讀并批評(píng)指點(diǎn)拿霉。

SAS編程實(shí)踐---宏:按系統(tǒng)術(shù)語、首選術(shù)語和嚴(yán)重程度分層次計(jì)算受試者發(fā)生不良反應(yīng)(AE)例數(shù)和例次

SAS編程實(shí)踐---宏:按系統(tǒng)術(shù)語和首選術(shù)語分層次計(jì)算受試者發(fā)生不良反應(yīng)(AE)例數(shù)和例次

文章中呈現(xiàn)的是最終的宏代碼咱扣,但是在實(shí)際編寫過程中绽淘,步驟順序可能會(huì)和文章的結(jié)構(gòu)順序不同,畢竟寫文章和寫代碼還是有區(qū)別的闹伪。

代碼編寫時(shí)可能會(huì)經(jīng)歷沪铭,編寫---替換修改---增添---替換修改---...,這樣的步驟很多次才形成了最終的代碼偏瓤。

不過目前我堅(jiān)持的編寫宏程序的總體結(jié)構(gòu)還是如之前的文章一樣杀怠,也即:

*_1. pre-processing;
*_2.main statistical steps;
*_3 processing step of stat;
* _4.output steps;
    1. 預(yù)處理(宏變量的處理和輸入數(shù)據(jù)集的預(yù)處理)
    1. 主要的統(tǒng)計(jì)步驟
    1. 統(tǒng)計(jì)步驟后的處理
    1. 輸出步驟

基本原則

在實(shí)際操作中,最開始進(jìn)行目標(biāo)表格拆解分析模擬數(shù)據(jù)生成后厅克,進(jìn)行到宏程序代碼編寫步驟驮肉,會(huì)先進(jìn)行上述第1步中的輸入數(shù)據(jù)集的預(yù)處理第2步的統(tǒng)計(jì)步驟

這兩步是處理數(shù)據(jù)的最核心的步驟已骇,而其他的步驟离钝,更多是為了進(jìn)行表格拼接修改,使達(dá)到目標(biāo)表格樣式褪储;或者基于SAS宏的”文本替換“原則進(jìn)行的輔助步驟卵渴。

  • 說明一下,很多步驟使用PROC SQL語句會(huì)簡單許多鲤竹,但是本文中除了少量的宏變量的賦值會(huì)使用PROC SQL語句以外浪读,還是以使用基礎(chǔ)DATA步和過程步為主昔榴。

準(zhǔn)備步驟

說了這么多,下文我便一步一步實(shí)踐去編寫一個(gè)”基本描述性統(tǒng)計(jì)量表格“的宏的編寫碘橘。

目標(biāo)表格拆解分析

1

圖中是將要生成的目標(biāo)表格的模板:

  1. 指明了數(shù)值型變量互订,進(jìn)行核心統(tǒng)計(jì)步proc means需要計(jì)算的統(tǒng)計(jì)指標(biāo)有哪些;需要注意nminssing痘拆,可能存在分析數(shù)據(jù)集里觀測(cè)的缺失仰禽,所以我一般使用adsl數(shù)據(jù)集進(jìn)行各組受試者數(shù)量的確定;

  2. 表明了在拼接步需要拼接成的樣式纺蛆,需要注意吐葵,小數(shù)點(diǎn)位數(shù)的保留問題,因此需要在核心步驟之外進(jìn)行小數(shù)點(diǎn)位數(shù)保留問題的處理桥氏;

  3. 合計(jì)列是否計(jì)算温峭,需要條件選擇語句,以及相應(yīng)的數(shù)據(jù)預(yù)處理和計(jì)算步驟字支;

  4. 指明了分組凤藏,分組變量是必須存在的,且我一般盡量會(huì)處理為數(shù)值型堕伪。

模擬數(shù)據(jù)生成

通過目標(biāo)表格的拆解揖庄,明確了那些模擬數(shù)據(jù)需要那些變量。

分析數(shù)據(jù)集

分析數(shù)據(jù)集必須要包含了分組變量待統(tǒng)計(jì)分析的數(shù)值型變量刃跛。

2

我使用如下代碼生成模擬數(shù)據(jù):

%let seed1 = 33333333;

data ad0;
    do ii = 1 to 3;
        armn = ii;
        arm = cats("第",put(ii, best.) ,"組");

        do jj = 1 to 100;
            usubjid =  cats( "X",put(ii, best.) ,"-", put(jj, z3.));

            if mod(jj,3) = 0 then
                SEX = "女";
            else SEX = "男";
            HEIGHT = round(ranuni(&seed1.)*30 + 155, 0.1);
            output;
        end;
    end;
run;

同時(shí)抠艾,人為地造成了若干條觀測(cè)的缺失

data ad;
    set ad0;

    if jj in (2  13  17) and sex = "男" then
        delete;

    if jj in (12  7  24) and sex = "女" then
        delete;
run;

adsl數(shù)據(jù)集

3

adsl數(shù)據(jù)集主要用來計(jì)算受試者的數(shù)量,需要包含分組變量信息桨昙;

data adsl;
    do ii = 1 to 3;
        armn = ii;
        arm = cats("第",put(ii, best.) ,"組");
        do jj = 1 to 100;
            usubjid =  cats( "X",put(ii, best.) ,"-", put(jj, z3.));
            output;
        end;
    end;
run;

宏編寫步驟

模擬數(shù)據(jù)有了检号,明確了所需的統(tǒng)計(jì)指標(biāo),接下來就是先使用模擬數(shù)據(jù)把數(shù)據(jù)預(yù)處理統(tǒng)計(jì)的步驟寫出來蛙酪,生成目標(biāo)表格齐苛。

數(shù)據(jù)預(yù)處理和核心統(tǒng)計(jì)步驟

分組統(tǒng)計(jì)

  • 我們這個(gè)例子是進(jìn)行身高的描述性統(tǒng)計(jì),使用proc means根據(jù)分組變量統(tǒng)計(jì)HEIGHT桂塞;
* _2.main statistical steps; ;
* _2.1 Calculation of target variable statistics;
* _2.1.1  by group ;
* _2.1.1.1 target variable;
proc means data=ad  noprint ;
var HEIGHT;
by armn ;
output out=_bygrpm0 N= n nmiss=nmiss mean=mean STD=std  median = mid  q1=q1 q3= q3  max=max min=min;
run;
  • 分組統(tǒng)計(jì)adsl數(shù)據(jù)集中受試者的數(shù)量,為了計(jì)算nmissing指標(biāo)凹蜂;
* _2.1.1.2  Calculation of the number of every group;
proc freq data=adsl ;
table armn / out=_bygrpnum;
run;

注意,這一步也可以使用proc sql進(jìn)行計(jì)算然后賦值為宏變量會(huì)更加簡單阁危。

  • 合并上述兩個(gè)數(shù)據(jù)集
* _2.1.1.3 combine ;
proc sort data=_bygrpm0; by armn;run;

data _bygrp;
merge _bygrpm0
_bygrpnum(drop =  percent);
by armn;
run;

分組統(tǒng)計(jì)目標(biāo)變量到這里其實(shí)都準(zhǔn)備好了玛痊。

合計(jì)列

接下來是合計(jì)列指標(biāo)的計(jì)算;

  • 合計(jì)數(shù)據(jù)的預(yù)處理
*_1. pre-processing;
* _1.2.1 for sum column ;
data _adsum;
set ad;
armn = 999;
arm = "合計(jì)";
run;

data _adslall;
set adsl;
armn = 999;
arm = "合計(jì)";
run;
  • 合計(jì)列統(tǒng)計(jì)量的計(jì)算
* _2.main statistical steps; ;
* _2.2 Calculation of  sum column statistics;
* _2.2.1 Calculation of  sum column  of target variable statistics;
proc means data=_adsum  noprint ;
var HEIGHT;
by armn;
output out=_summ0(drop=_TYPE_)  N= n nmiss=nmiss mean=mean STD=std median = mid q1=q1 q3= q3  max=max min=min;
run;
  • 受試者總數(shù)狂打,為了構(gòu)建nmissing
* _2.2.2 Calculation of number of all subject;
proc freq data=_adslall noprint;
table armn / out=_sumnum;
proc sort ; by armn;
run;
  • 合并上述兩個(gè)數(shù)據(jù)集
* _2.2.3 combine ;
proc sort data=_summ0; by armn;run;

data _sum;
merge _summ0
_sumnum(drop =  percent);
by armn;
run;

統(tǒng)計(jì)后處理-數(shù)據(jù)拼接

接下來的步驟擂煞,我一般會(huì)這樣做,根據(jù)橫向排列的統(tǒng)計(jì)量趴乡,使用字符拼接函數(shù)拼成所需的樣式对省,然后使用proc transpose 進(jìn)行重新的塑型生成目標(biāo)樣式蝗拿。

不過為了簡便些,可以先把分組統(tǒng)計(jì)的和最后的合計(jì)列數(shù)據(jù)集先set蒿涎,然后再進(jìn)行后續(xù)步驟哀托,在宏代碼里,就涉及到條件判斷了劳秋。文章中為了分步展示仓手,我先賦值個(gè)宏變量(包裝進(jìn)宏時(shí)刪除就好),拆開步驟單獨(dú)展示俗批。

判斷是否計(jì)算合計(jì)列的宏參數(shù)我預(yù)設(shè)為rowsumyn俗或,為了提醒自己市怎,我會(huì)在日志中產(chǎn)生一個(gè)警告

%let rowsumyn = Y;


* _3 processing step of stat;
* _3.1 processing step of stat;
%if %sysfunc(upcase(&rowsumyn.)) = %str(Y) %then %do;
%put WARNING: 將計(jì)算合計(jì)列;

data _dt4comb;
set _bygrp
_sum;
run;
%end;

%else %do;
%put WARNING: 不計(jì)算合計(jì)列;
data _dt4comb;
set _bygrp;
run;
%end;
  • 接下來是拼接步驟
* _3.2 Variable construction of the target format;
data _combdt;
length  _1nnmiss _2meansd _3median _4q1q3  _5minmax  $200.;
set _dt4comb;
_1nnmiss =cats( strip(put(n ,8.0)) , "(",strip(put(count - n , 8.0)), ")");
_2meansd = cats( strip(put( round(mean , 0.01 ), 8.2) ) ,  "(" ,strip(put( round(std, 0.001), 8.3) )   , ")");
_3median =  cats( strip(put( round(mid , 0.01 ) , 8.2) ) );
_4q1q3 = cats( strip(put( round(q1 , 0.01 ) , 8.2) ) ,  "~" ,strip(put( round(q3 , 0.01 )  , 8.2) )   );
_5minmax = cats( strip(put(  round(min , 0.01 ) , 8.1) ) ,  "~" ,strip(put(   round(max , 0.01 ) , 8.1) )   );
keep armn  _1nnmiss  _2meansd  _3median   _4q1q3   _5minmax;
proc sort; by armn;
run;  

注意岁忘,這個(gè)步驟的代碼是初步的,因?yàn)檫@里是硬性規(guī)定了位數(shù)的取舍区匠,而實(shí)際上干像,是還有一步關(guān)于小數(shù)位數(shù)問題的宏變量的預(yù)處理

統(tǒng)計(jì)后處理-數(shù)據(jù)塑形

  • 之后通過2次數(shù)據(jù)塑形驰弄,形成目標(biāo)表格的樣式
* _3.3 transpose;
proc transpose data=_combdt  out=_trans1;
var   _1nnmiss  _2meansd  _3median   _4q1q3   _5minmax;
by armn;
proc sort; by _NAME_  ;
run;

proc transpose data=_trans1  out=_trans2 prefix= _grp;
id armn;
var  col1;
by _NAME_ ;
run;

如下圖所示:

可以看到麻汰,和目標(biāo)表格基本上只有細(xì)節(jié)上的差別的,這些差別的處理就是一些輔助步驟要解決的問題了戚篙。


替換并包裝成宏

宏參數(shù)及替換

接下來就是確定宏參數(shù)名稱五鲫,這個(gè)宏我限定如下這些參數(shù):

%macro MeanT(
libin=,
dtin=,
adsl=,
var=,
grpvarn=,
rowsumyn=,
label=,
append=,
libout,
dtout=
);

替換這一步我就不展示。使用SAS EG工具欄-編輯-替換或者Ctrl + H進(jìn)行代碼替換岔擂。

然后包裝進(jìn)宏里位喂,試著運(yùn)行一下。

注意到這一步乱灵,不要最后的4個(gè)參數(shù)塑崖,是可以運(yùn)行成功的。

小數(shù)點(diǎn)位數(shù)

不同的統(tǒng)計(jì)指標(biāo)要保留的小數(shù)點(diǎn)位數(shù)是不一樣的痛倚,更和原始數(shù)據(jù)的位數(shù)有關(guān)规婆。

我不知道不同公司是否要求有所不同,我依據(jù)我們公司的原則蝉稳,限定如下:

-nnmissing都是整數(shù)部分抒蚜;

  • minmax指標(biāo)保留位數(shù),和原始數(shù)據(jù)最大小數(shù)位數(shù)一致耘戚;
  • 當(dāng)原始數(shù)據(jù)最大小數(shù)位數(shù)(decmax)小于等于2時(shí):mean嗡髓、median、q1q3保留decmax + 1位毕莱;std保留decmax + 2位器贩;
  • 當(dāng)原始數(shù)據(jù)最大小數(shù)位數(shù)(decmax)等于3時(shí):mean颅夺、median、q1q3保留decmax + 1位蛹稍;std保留4位吧黄;
  • 當(dāng)原始數(shù)據(jù)最大小數(shù)位數(shù)(decmax)大于3時(shí):mean、median唆姐、q1拗慨、q3std均保留4位;

好的奉芦,根據(jù)這些原則赵抢,下面利用代碼實(shí)現(xiàn)。

  • 待分析變量的小數(shù)位數(shù)宏變量
data _stdt0;
set &libin..&dtin.;
run;

data _adsl;
set &adsl.;
run;

* _1. pre-processing;
*  _1.1 decimals ;

data _dec;
set  _stdt0;
dec = length(scan(strip(put(&var., best.)),2,"."));
if not index(&var.,".") then dec = 0;
run;

proc sql ;
select max(dec) into: decmax 
from _dec
;
quit;
%put 最大小數(shù)位數(shù):&decmax.;

通過上面的代碼声功,將待分析變量的最大小數(shù)位數(shù)賦值給宏變量decmax烦却。

  • 拼接步驟代碼的修改

這樣子,上述拼接步驟的代碼就可以按照小數(shù)點(diǎn)保留的原則進(jìn)行修改了先巴,修改后的代碼如下:

* _3.2 Variable construction of the target format;
data _combdt;
length  _1nnmiss _2meansd _3median _4q1q3  _5minmax  $200.;
set _dt4comb;
_1nnmiss =cats( strip(put(n ,8.0)) , "(",strip(put(count - n , 8.0)), ")");
_5minmax = cats( strip(put(  round(min , 10**-( &decmax.) ) , 8.%eval( &decmax.)) ) ,  "~" ,strip(put(   round(max , 10**-( &decmax.) ) , 8.%eval( &decmax.)) ) );

%if &decmax. <= 2 %then %do;
_2meansd = cats( strip(put( round(mean , 10**-( &decmax. + 1) ),  8.%eval( &decmax. + 1) ) ) ,  "(" ,strip(put( round(std,  10**-( &decmax. + 2)),   8.%eval( &decmax. + 2)) )   , ")");
_3median =  cats( strip(put( round(mid ,  10**-( &decmax. + 1) ) ,   8.%eval( &decmax. + 1) ) ) );
_4q1q3 = cats( strip(put( round(q1 , 10**-( &decmax. + 1) ) ,  8.%eval( &decmax. + 1) ) ) ,  "~" ,strip(put( round(q3 ,  10**-( &decmax. + 1)  )  ,  8.%eval( &decmax. + 1) ) )   );
%end;

%if &decmax. = 3 %then %do;
_2meansd = cats( strip(put( round(mean , 10**-( &decmax. + 1) ),  8.%eval( &decmax. + 1) ) ) ,  "(" ,strip(put( round(std,  0.0001),   8.4) )   , ")");
_3median =  cats( strip(put( round(mid ,  10**-( &decmax. + 1) ) ,   8.%eval( &decmax. + 1) ) ) );
_4q1q3 = cats( strip(put( round(q1 , 10**-( &decmax. + 1) ) ,  8.%eval( &decmax. + 1) ) ) ,  "~" ,strip(put( round(q3 ,  10**-( &decmax. + 1)  )  ,  8.%eval( &decmax. + 1) ) )   );
%end;

%if &decmax. >3 %then %do;
_2meansd = cats( strip(put( round(mean , 0.0001 ),  8.4 ) ) ,  "(" ,strip(put( round(std,  0.0001),   8.4) )   , ")");
_3median =  cats( strip(put( round(mid ,  0.0001 ) ,   8.4 ) ) );
_4q1q3 = cats( strip(put( round(q1 ,0.0001 ) ,  8.4 ) ) ,  "~" ,strip(put( round(q3 ,  0.0001  )  ,  8.4 ) )   );
%end;
keep &grpvarn.  _1nnmiss  _2meansd  _3median   _4q1q3   _5minmax;
proc sort; by &grpvarn.;
run;  

列名的修改

*_3.4 rename column;
    proc contents data=_trans2 out=_info   noprint;

    proc sort;
        by varnum;
    run;

    proc sql   noprint;
        select count(distinct NAME) ,  NAME into: varn, :vnam1 -:vnam99 from _info;
    quit;

    data _&dtout.;
        set _trans2;
        %do ii = 1 %to &varn.;
            %let jj = %eval(&ii. - 1);
            rename &&vnam&ii. = C&jj.;
        %end;
    run;

label第一列的修改

在目標(biāo)表格的第一行是我們統(tǒng)計(jì)的指標(biāo)的名稱其爵,添加代碼如下:

* _3.5 label ;
    data _row1;
        length C0 $200.;
        C0 = cats("&label.");
    run;

    data _&dtout._;
        set _row1 
            _&dtout.;
    if c0 = "_1nnmiss" then C0 = "n(nmisssing)";
    if c0 = "_2meansd" then C0 = "Mean(SD)";
    if c0 = "_3median" then C0 = "Median";
    if c0 = "_4q1q3" then C0 = "Q1~Q3";
    if c0 = "_5minmax" then C0 = "Min~Max";
    run;

append

有時(shí)候要統(tǒng)計(jì)的變量不止一個(gè),而我們又想下一個(gè)跟在上一個(gè)之后伸蚯,因此設(shè)置了一個(gè)append參數(shù)

* _3.6 append ;
%if %sysfunc(upcase(&append.)) = %str(Y) and  %sysfunc(exist(&dtout., data) )  %then %do;

data &dtout.;
set %if %sysfunc(exist(&dtout., data) ) %then &dtout.;  _&dtout._ ;
run;
%end;
%else %do;
%put WARNING: 未追加數(shù)據(jù)集;

data &dtout.;
set  _&dtout._ ;
run;

%end;

數(shù)據(jù)集輸出和清除臨時(shí)數(shù)據(jù)集

*  _4 output data ;
*  _4.1 output ;
data &libout..&dtout.;
set &dtout.;
run;

*  _4.2 remove temp datasets ;
proc datasets lib=work;
delete _:;
run;

總結(jié)

以上就是我寫這個(gè)宏的最主要代碼摩渺,還有一些小判斷就不展示了。

完整代碼如下:

%macro MeanT(
libin=,
dtin=,
adsl=,
var=,
grpvarn=,
rowsumyn=,
label =,
append=,
libout=,
dtout=
);


data _stdt0;
set &libin..&dtin.;
run;

data _adsl;
set &adsl.;
run;

* _1. pre-processing;
*  _1.1 decimals ;

data _dec;
set  _stdt0;
dec = length(scan(strip(put(&var., best.)),2,"."));
if not index(&var.,".") then dec = 0;
run;

proc sql ;
select max(dec) into: decmax 
from _dec
;
quit;
%put 最大小數(shù)位數(shù):&decmax.;

* _1.2.1 for sum column ;
data _adsum;
set _stdt0;
&grpvarn. = 999;
arm = "合計(jì)";
run;

data _adslall;
set  _adsl;
&grpvarn. = 999;
arm = "合計(jì)";
run;

* _2.main statistical steps; ;
* _2.1 Calculation of target variable statistics;
* _2.1.1.1 by group;
proc means data=_stdt0  noprint ;
var &var.;
by &grpvarn. ;
output out=_bygrpm0 N= n nmiss=nmiss mean=mean STD=std  median = mid  q1=q1 q3= q3  max=max min=min;
run;


* _2.1.1.2 Calculation of number of every group;
proc freq data=_adsl noprint;
table &grpvarn. / out=_bygrpnum;
proc sort ; by &grpvarn.;
run;

* _2.1.1.3 combine ;
proc sort data=_bygrpm0; by &grpvarn.;run;

data _bygrp;
merge _bygrpm0
_bygrpnum(drop =  percent);
by &grpvarn.;
run;


* _2.main statistical steps; ;
* _2.2 Calculation of  sum column statistics;
* _2.2.1 Calculation of  sum column  of target variable statistics;
proc means data=_adsum  noprint ;
var &var.;
by &grpvarn.;
output out=_summ0(drop=_TYPE_)  N= n nmiss=nmiss mean=mean STD=std median = mid q1=q1 q3= q3  max=max min=min;
run;

* _2.2.2 Calculation of number of all subject;
proc freq data=_adslall noprint;
table &grpvarn. / out=_sumnum;
proc sort ; by &grpvarn.;
run;


* _2.2.3 combine ;
proc sort data=_summ0; by &grpvarn.;run;

data _sum;
merge _summ0
_sumnum(drop =  percent);
by &grpvarn.;
run;


* _3 processing step of stat;
* _3.1 processing step of stat;
%if %sysfunc(upcase(&rowsumyn.)) = %str(Y) %then %do;
%put WARNING: 將計(jì)算合計(jì)列;

data _dt4comb;
set _bygrp
_sum;
run;
%end;
%else %do;
%put WARNING: 不計(jì)算合計(jì)列;
data _dt4comb;
set _bygrp;
run;
%end;



* _3.2 Variable construction of the target format;
data _combdt;
length  _1nnmiss _2meansd _3median _4q1q3  _5minmax  $200.;
set _dt4comb;
_1nnmiss =cats( strip(put(n ,8.0)) , "(",strip(put(count - n , 8.0)), ")");
_5minmax = cats( strip(put(  round(min , 10**-( &decmax.) ) , 8.%eval( &decmax.)) ) ,  "~" ,strip(put(   round(max , 10**-( &decmax.) ) , 8.%eval( &decmax.)) ) );

%if &decmax. <= 2 %then %do;
_2meansd = cats( strip(put( round(mean , 10**-( &decmax. + 1) ),  8.%eval( &decmax. + 1) ) ) ,  "(" ,strip(put( round(std,  10**-( &decmax. + 2)),   8.%eval( &decmax. + 2)) )   , ")");
_3median =  cats( strip(put( round(mid ,  10**-( &decmax. + 1) ) ,   8.%eval( &decmax. + 1) ) ) );
_4q1q3 = cats( strip(put( round(q1 , 10**-( &decmax. + 1) ) ,  8.%eval( &decmax. + 1) ) ) ,  "~" ,strip(put( round(q3 ,  10**-( &decmax. + 1)  )  ,  8.%eval( &decmax. + 1) ) )   );
%end;

%if &decmax. = 3 %then %do;
_2meansd = cats( strip(put( round(mean , 10**-( &decmax. + 1) ),  8.%eval( &decmax. + 1) ) ) ,  "(" ,strip(put( round(std,  0.0001),   8.4) )   , ")");
_3median =  cats( strip(put( round(mid ,  10**-( &decmax. + 1) ) ,   8.%eval( &decmax. + 1) ) ) );
_4q1q3 = cats( strip(put( round(q1 , 10**-( &decmax. + 1) ) ,  8.%eval( &decmax. + 1) ) ) ,  "~" ,strip(put( round(q3 ,  10**-( &decmax. + 1)  )  ,  8.%eval( &decmax. + 1) ) )   );
%end;

%if &decmax. >3 %then %do;
_2meansd = cats( strip(put( round(mean , 0.0001 ),  8.4 ) ) ,  "(" ,strip(put( round(std,  0.0001),   8.4) )   , ")");
_3median =  cats( strip(put( round(mid ,  0.0001 ) ,   8.4 ) ) );
_4q1q3 = cats( strip(put( round(q1 ,0.0001 ) ,  8.4 ) ) ,  "~" ,strip(put( round(q3 ,  0.0001  )  ,  8.4 ) )   );
%end;
keep &grpvarn.  _1nnmiss  _2meansd  _3median   _4q1q3   _5minmax;
proc sort; by &grpvarn.;
run;  


* _3.3 transpose;
proc transpose data=_combdt  out=_trans1;
var   _1nnmiss  _2meansd  _3median   _4q1q3   _5minmax;
by &grpvarn.;
proc sort; by _NAME_  ;
run;

proc transpose data=_trans1  out=_trans2 prefix= _grp;
id &grpvarn.;
var  col1;
by _NAME_ ;
run;

*_3.4 rename column;
    proc contents data=_trans2 out=_info   noprint;

    proc sort;
        by varnum;
    run;

    proc sql   noprint;
        select count(distinct NAME) ,  NAME into: varn, :vnam1 -:vnam99 from _info;
    quit;

    data _&dtout.;
        set _trans2;
        %do ii = 1 %to &varn.;
            %let jj = %eval(&ii. - 1);
            rename &&vnam&ii. = C&jj.;
        %end;
    run;

* _3.5 label ;
    data _row1;
        length C0 $200.;
        C0 = cats("&label.");
    run;

    data _&dtout._;
        set _row1 
            _&dtout.;
    if c0 = "_1nnmiss" then C0 = "n(nmisssing)";
    if c0 = "_2meansd" then C0 = "Mean(SD)";
    if c0 = "_3median" then C0 = "Median";
    if c0 = "_4q1q3" then C0 = "Q1~Q3";
    if c0 = "_5minmax" then C0 = "Min~Max";
    run;

* _3.6 append ;
%if %sysfunc(upcase(&append.)) = %str(Y) and  %sysfunc(exist(&dtout., data) )  %then %do;

data &dtout.;
set %if %sysfunc(exist(&dtout., data) ) %then &dtout.;  _&dtout._ ;
run;
%end;
%else %do;
%put WARNING: 未追加數(shù)據(jù)集;

data &dtout.;
set  _&dtout._ ;
run;

%end;

*  _4 output data ;
*  _4.1 output ;
data &libout..&dtout.;
set &dtout.;
run;

*  _4.2 remove temp datasets ;
proc datasets lib=work;
delete _:;
run;

%mend;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末剂邮,一起剝皮案震驚了整個(gè)濱河市摇幻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌挥萌,老刑警劉巖绰姻,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瑞眼,居然都是意外死亡龙宏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門伤疙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來银酗,“玉大人,你說我怎么就攤上這事徒像∈蛱兀” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵锯蛀,是天一觀的道長灭衷。 經(jīng)常有香客問我,道長旁涤,這世上最難降的妖魔是什么翔曲? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任迫像,我火速辦了婚禮,結(jié)果婚禮上瞳遍,老公的妹妹穿的比我還像新娘闻妓。我一直安慰自己,他們只是感情好掠械,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布由缆。 她就那樣靜靜地躺著,像睡著了一般猾蒂。 火紅的嫁衣襯著肌膚如雪均唉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天肚菠,我揣著相機(jī)與錄音舔箭,去河邊找鬼。 笑死案糙,一個(gè)胖子當(dāng)著我的面吹牛限嫌,可吹牛的內(nèi)容都是我干的靴庆。 我是一名探鬼主播时捌,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼炉抒!你這毒婦竟也來了奢讨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤焰薄,失蹤者是張志新(化名)和其女友劉穎拿诸,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體塞茅,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亩码,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了野瘦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片描沟。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鞭光,靈堂內(nèi)的尸體忽然破棺而出吏廉,到底是詐尸還是另有隱情,我是刑警寧澤惰许,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布席覆,位于F島的核電站,受9級(jí)特大地震影響汹买,放射性物質(zhì)發(fā)生泄漏佩伤。R本人自食惡果不足惜聊倔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望生巡。 院中可真熱鬧方库,春花似錦、人聲如沸障斋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽垃环。三九已至邀层,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間遂庄,已是汗流浹背寥院。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涛目,地道東北人秸谢。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像霹肝,于是被迫代替她去往敵國和親估蹄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容