2024年6月16日

〔SAS〕PROC MEANS 不只用做描述統計而已

實務分析工作中,PROC MEANS除了用來做描述統計外,更多是用來做資料的彙整,例如健保資料庫分析中,因病患有多次就診或用藥紀錄,需透過適當的整合,或稱為「歸人」在能進行後續的分析,這時PROC MEANS為重要的幫手了。

本篇內容將聚焦於使用PROC MEANS的語法完成所需要資料處理的工作,但在介紹順序上沒有特別章法,大家就依據所需要語法而自行使用了喔。

依據慣例先建立範例資料檔以供後續練習。

data sample;
    do x=1 to 500;

        ran_var1=uniform(5);
            if ran_var1<0.5 then gender=0;
    else if ran_var1>0.5 then gender=1;
             if uniform(7)>=0.5 then drug=0;
    else drug=1;

        ran_var2=uniform(6);
            if 0<=ran_var2<0.3 then do;
                Older_Adults=1;
                drug=.;
                 end;
    else if ran_var2<0.6 then Older_Adults=2;
    else if ran_var2>0.6 then Older_Adults=3;

            if Older_Adults=1 then do;
                sbp=normal(1)*11+115;
                 dbp=normal(2)*8 +75;
            end;
    else    if Older_Adults=2 then do;
                sbp=normal(1)*13+120;
                dbp=normal(2)*9 +80;
            end;
     else    if Older_Adults=3 then do;
                sbp=normal(1)*17+135;
                dbp=normal(2)*12 +85;
            end;
        output;

    end;
    drop x ran_var: ;
run;


OUTPUT語法

PROC MEANS中加入OUTPUT 語法,因為我們不是要「看到報表」所以要記得使用NOPRINT這一個指令喔。

/*Output*/

proc means data=sample noprint  ;
    class gender Older_Adults ;
    var sbp dbp;
   output out=out_01 mean=;
run;

proc print data=out_01;
run;

上述語法中,我們將針對練習資料中的兩個分層變項(gender Older_Adults)跑出SBP(收縮壓)和DBP(舒張壓)的平均值,結果如下圖。

01

圖中可以看到PROC MEANS將gender和Older_Adults所有可能的組合和其對應的SBPDBP平均值計。所有組合包括4種,這可以透過 _TYPES_ 這一個變項的編號瞭解,簡單說明

_TYPES_=0:「不分gender和Older_Adults」的結果。

_TYPES_=1:只有Older_Adults中3個類別的的各自統計結果。

_TYPES_=3:gender和Older_Adults組合後的統計結果,例如gender=0和Older_Adults=1這樣的個案組合,SBP平均值為115.8,DBP平均值為75.7。

在PROC MEANS中還有另一種呈現_TYPES_的方式,需配合使用CHARTYPE指令,會將_TYPE_改為文字型態,而非數字型態,而文字型態會依據有沒有使用到特定CLASS變項,給予0或1。程式和結果如下,請自行依據所需使用適合的指令。

proc means data=sample noprint CHARTYPE ;
    class gender Older_Adults ;
    var sbp dbp;
    output out=out_01 mean=;
run;

proc print data=out_01;
run;

02

NWAY語法

在一般透過output輸出通常只會需要兩組變項均存在的所有組合,或_TYPE_最高的結果。

proc means data=sample noprint NWAY ;
     class gender Older_Adults ;
    var sbp dbp;
    output out=out_02 mean=;
run;

proc print data=out_02;
run;

03

TYPES語法

我偏愛使用TYPES語法,可比較「精準」控制需要的變項組合,先從最簡單的開始吧。

  • TYPES ():這裡的()表示總計或和記得意思。
  • TYPES A*B A*CTYPES A*(B C):得到A和B組合,及A和C組合的結果。
  • TYPES (A B)*(C D)TYPES A*C A*D B*C B*D
  • proc means data=sample noprint  ;
         class gender Older_Adults ;
        var sbp dbp;
        TYPES () ;
         output out=out_03 mean=;
    run;

    proc print data=out_03;
    run;

    04

    proc means data=sample noprint  ;
        class gender Older_Adults ;
        var sbp dbp;
        TYPE () gender Older_Adults;
         output out=out_03 mean=;
    run;

    proc print data=out_03;
    run;

    05 

    proc means data=sample noprint  ;
        class gender Older_Adults ;
        var sbp dbp;
        types () gender*Older_Adults;
        output out=out_03 mean=;
    run;

    proc print data=out_03;
    run;

    06

    proc means data=sample noprint  ;
        class gender Older_Adults drug ;
        var sbp dbp;
        types () gender*Older_Adults Older_Adults*drug;
        output out=out_03 mean=;
    run;

    proc print data=out_03;
    run;

    07

    AUTONAME語法

    如果要同時輸出兩個統計值,例如meanstd(標準差),沒有使用特別語法下,結果會變成…

    proc means data=sample noprint  ;
        class gender Older_Adults ;
        var sbp dbp;
        types () gender*Older_Adults;
        output out=out_04
                                mean=
                                 std= ;
    run;

    proc print data=out_04;
    run;

    08

    對,你沒看錯,只有跑出sbp和dbp的某一個統計值,比對一下應是mean的數值,要修正此錯誤只需將程式兩個預計輸出的統計量的等於之後加入『預計輸出的名稱』。

    • mean= sbp_mean dbp_mean
    • std=sbp_std dbp_std

    proc means data=sample noprint  ;
        class gender Older_Adults ;
        var sbp dbp;
        types () gender*Older_Adults;
        output out=out_04
                               mean= sbp_mean dbp_mean
                                std= sbp_std dbp_std;
    run;

    proc print data=out_04;
    run;

    09

    但有時要分析的變項(VAR)或要輸出的統計量比較多時,可以使用AUTONMAE語法,放置在輸出統計量最後面加入『/』後用AUTONAME

    proc means data=sample noprint  ;
        class gender Older_Adults ;
        var sbp dbp;
        types () gender*Older_Adults;
        output out=out_04
                                mean=
                                 std=
                    / AUTONAME;
    run;

    proc print data=out_04;
    run;

        11                     

    選取只特定變項需要的統計量

    如果現在遇到的情境是,只需要輸出dbp的平均值和標準差,及sbp的中位數,程式寫法可以改成

    proc means data=sample noprint  ;
        class gender Older_Adults ;
        var sbp dbp;
        types () gender*Older_Adults;
        output out=out_05
                            mean(dbp)= std(dbp)=
                            median(sbp)=
                     / autoname;
    run;

    proc print data=out_05;
    run;

    11


    輸出檔案配合Data Step Option

    別忘記『out=資料檔』之後也可以是用data step option喔,例如將沒用到的_TYPE_和_FREQ_變項刪除

    proc means data=sample noprint  ;
        class gender Older_Adults ;
        var sbp dbp;
        types () gender*Older_Adults;
        output out=out_06(drop=_type_ _freq_)
                            mean(dbp)= std(dbp)=
                            median(sbp)=
                     / autoname;
    run;

    proc print data=out_06;
    run;

    12

    同時輸出多個檔案

    在同一個PROC MEAN可以同時將所需的組合輸出至不同的檔案例如將總和及兩變項的組合分別拋到out_7a及out_7b中。

        

    proc means data=sample noprint  ;
        class gender Older_Adults ;
        var sbp dbp;
        types () gender*Older_Adults;
        output out=out_07a (where=(_type_=0))
                             mean= std=     / autoname;
        output out=out_07b (where=(_type_=3))
                            mean= std=     / autoname;
    run;

    title "out_07a";
    proc print data=out_07a;
    run;

    title "out_07a";
    proc print data=out_07b;
    run;

    13


    MISSING語法

    如果在分類變項互相之間有遺漏值,例如在範例資料中Older_Adults=1中均無drug的資料,此時可用MISSING語法,強迫將「drug=遺漏值」是唯一個組別,計算出相對應的統計量。

    proc means data=sample noprint MISSING;
        class  Older_Adults drug ;
        var sbp dbp;
        types () Older_Adults*drug;
        output out=out_08 mean= /autoname;
    run;

    proc print data=out_08;
    run;

    14

    COMPLETETYPES & PRELOADFMT語法

    如果還是想要將drug兩種組別「強迫」呈現於輸出檔案中,先建立drug的自訂格式,在使用「COMPLETETYPESPRELOADFMT」語法即可達成,但也因為這兩組本來就不存在Older_Adults=1中,因此相對應的統計量也會無法計算。

    /*自訂格式*/
    proc format;
        value drugF 0="無" 1="有";
        value OlderF 1="少" 2="中" 3="老";
    run;

    proc means data=sample noprint COMPLETETYPES;
        format drug drugF. Older_Adults OlderF.;
        class  Older_Adults drug /PRELOADFMT;
        var sbp dbp;
        types () Older_Adults*drug;
        output out=out_09 mean= /autoname;
    run;

    proc print data=out_09;
    run;

    15

    沒有留言:

    張貼留言