2020年2月15日

〔SAS〕使用SGPLOT繪散佈圖及程式巨集化

散佈圖(Scatter Plot、Scatter Diagram)亦稱為散布圖、相關圖等。目前在SAS繪製散佈圖有兩個較為簡單方法,一為使用PROC CORR,相關語法可見SAS官網的說明,用PROC CORR的方法相當簡單,而且同時會把人數、相關係數、檢定的P值呈現於圖中,但如要修改圖形或增加其他說明限制就很大了。

另一方法為本篇將分享的PROC SGPLOT,但限制為不會自動在圖形上呈現人數、相關係數和檢定的P值,此限制可透過巨集的幫忙而增加至圖形中,以PROC SGPLOT所繪統計圖,在之後需的編修彈性就高很多。

最後我們會把整組程式以改編為巨集程式,方便未來使用。

散佈圖(scatter plot)+橢圓圖(prediction ellipse)+迴歸線(regression line):

散佈圖(scatter plot)+橢圓圖(prediction ellipse)+迴歸線(regression line)

建立模擬資料檔於【程式01】。

模擬資料隨機產生父母身高合計與11~12歲兒童身高,散佈圖主要呈現父母身高合計與兒童身高相關性。

/*程式01*/
data height_1 (drop=i);;
    do i=1 to 1000;
        p_height=normal(10)*8.5+331.6;
        se=normal(20)*0.015+0.299;
        int=normal(30)*4.905+49.125;
        c_height=int+se*p_height;
        output;
    end;
run;     

在SGPLOT無法計算相關係數等統計量,需透過PRCO CORR產生相關的統計量,再將需要的統計量轉成巨集變項,提供後續繪圖使用。將相關係數、P值和人數轉成巨集變數的程式於【程式02】。

/*程式02*/
    ods output pearsoncorr =_pearsoncorr_ SimpleStats =_SimpleStats_  ;
    proc corr data=height_1 /*outp=pearson_corr*/ /*plots=scatter */;
    var p_height c_height;
    run;quit;

    proc sql noprint;
        /*擷取P值和相關係數*/
        select  round(p_height,0.0001) , pp_height format=pvalue8.4 into: mv_corr ,: mv_corr_p
        from _pearsoncorr_
        where variable in ("c_height" ) ;
        /*擷取人數*/
        select  NObs into: mv_obs
        from _simplestats_  ;
    quit;
    %put pearson correlation=&mv_corr  p-value=&mv_corr_p. obs=&mv_obs;

稍微說明【程式02】比較特別的語法:

「ods output」:可將SAS報表轉換成資料檔,相關的說明請見ODS OUTPUT Statement。使用該語法比較常見的困擾為不知報表的名稱,此時可一併與「ODS TRACE ON」及「ODS TRACE OFF」一起服用,在開啟ODS TRACE ON後可於LOG中見到報表的名稱,執行 ODS TRACE OFF則關閉功能,實際應用可參考SAS台灣官網的應用範例SAS Output Delivery System (ODS)

「PROC SQL…INTO:」:此語法可將「單一數字」放到指定的巨集變項中。在這裡我們將相關係數放到mv_corr、P值放到mv_corr_p、人數放到mv_obs。

【程式03】為主要繪圖的程式

/*程式03*/

ods html gpath = "e:\temp\"  image_dpi=300  style=htmlblue;
ods graphics on / reset=all reset=index noborder height=6in width =6in
                                 antialiasmax=10000  imagename = "圖" imagefmt =png ;
ods results off;
        proc sgplot data=height_1  ;
             scatter x=p_height y=c_height /  markerattrs=(size=2 symbol=circlefilled color=red ) name="dot";
            ellipse x=p_height y=c_height/ name="ellipse";
            reg  x=p_height y=c_height /nomarkers 
                                             lineattrs=(pattern=1 color=gray thickness=0.6%) name="reg";
             keylegend "ellipse" "reg" /location= inside noborder;
                styleattrs backcolor=white wallcolor=white;
            inset ("Observations" = "&mv_obs"
                        "Correlation  "="&mv_corr"
                        "p-Value  "="&mv_corr_p")/ border;
            xaxis valueattrs=(size=8) label="父母身高合計";
            yaxis  valueattrs=(size=8) label="小孩身高";
         run;
ods results  on; title;quit;   

「scatter」:繪製散佈圖的主要語法。markeratters可設定散佈圖『點』的樣式。name給於此語法一個名稱,提供後續keylegend設定哪些圖例需要呈現。

「ellipse」:95% prediction ellipse,繪製雙變項的多元常態分佈圖(Multivariate normal distribution)。

「reg」:繪製線性迴歸線。

「keylegent」:設定圖例(legend)的位置和樣式,及上述哪些圖形的圖例需要呈現,目前語法不呈現散佈圖的圖例。

「inset」:在圖中增加文字,【程式02】產生的巨集變項套用於此處。

「xaxis」:設定X軸的外觀。

「yaxis」:設定Y軸的外觀。

圖


《程式巨集化》

希望巨集化之後能達到的彈性,包括「資料檔名稱」、「變項名稱」、「軸的名稱」、「圖片輸出目錄」、「圖檔名稱」均可彈性輸入,同時可依據需求繪製或不繪製橢圓圖或迴歸線。修該完成的巨集程式於【程式04】。

/*程式04*/

%macro scatter_plot (data=, x=, y=, xlabel=, ylabel=, outpath=,outfile=,ellipse=YES, reg=YES);
   
    ods output pearsoncorr =pearsoncorr ;
    proc corr data=&data plots=scatter ;
    var &x &y;
    run;quit;


    proc sql noprint;
        select  round(&x ,0.0001) , p&x format=pvalue8.4 into: mv_corr ,: mv_corr_p
        from pearsoncorr
        where variable in ("&y" ) ;
    quit;
    %put pearson correlation=&mv_corr  p-value=&mv_corr_p.;

ods html gpath = "&outpath"  image_dpi=300  style=htmlblue;
ods graphics on / reset=all reset=index noborder height=6in width =6in
                                 antialiasmax=10000  imagename = "&outfile" imagefmt =png ;
ods results off;
        proc sgplot data=&data  ;
             /*繪製散佈圖*/
            scatter x=&x y=&y / markerattrs=(size=2 symbol=circlefilled color=red) name="dot";
            /*繪製橢圓圖*/
            %if %upcase(&ellipse)=YES %then %do;
             ellipse x=&x y=&y / name="ellipse";
            %end;
             /*繪製迴歸線*/
            %if %upcase(&reg)=YES %then %do;
             reg  x=&x y=&y /nomarkers  lineattrs=(pattern=1 color=gray thickness=0.6%) name="reg";
            %end;
            /*定義legen的呈現和位置*/
            keylegend "ellipse" "reg" /location= inside noborder;
               styleattrs backcolor=white wallcolor=white;
            /*增加相關係數和P值的文字*/
            inset ("correlation  "="&mv_corr"
                        "p-value  "="&mv_corr_p")/ border;
            /*設定X軸*/
            xaxis valueattrs=(size=8) label="&xlabel";
            /*設定Y軸*/
            yaxis  valueattrs=(size=8) label="&ylabel";
        run;
ods results  on; title;quit;
%mend scatter_plot;

使用方法為【程式05】

/*程式05*/
data height_2 (drop=i);;
    do i=1 to 1000;
        x_height=normal(100)*8.5+331.6;
        se=normal(200)*0.015+0.299;
        int=normal(300)*4.905+49.125;
        y_height=int+se*x_height;
        output;
    end;
run;
/*option mprint;*/
/*繪製散佈圖、橢圓圖、迴歸線*/
%scatter_plot (data=height_2, x=x_height, y=y_height, xlabel=父母身高加總, ylabel=孩童身高, outpath=e:\temp\,outfile=圖A );
/*繪製散佈圖、橢圓圖*/
%scatter_plot (data=height_2, x=x_height, y=y_height, xlabel=父母身高加總, ylabel=孩童身高, outpath=e:\temp\,outfile=圖B ,reg=no);
/*繪製散佈圖,排除其他圖形*/
%scatter_plot (data=height_2, x=x_height, y=y_height, xlabel=父母身高加總, ylabel=孩童身高, outpath=e:\temp\,outfile=圖C ,ellipse=no, reg=no);
/*繪製散佈圖,迴歸線,交換X軸和Y軸的變項*/
%scatter_plot (data=height_2, x=y_height, y=x_height, xlabel=孩童身高, ylabel=父母身高加總, outpath=e:\temp\,outfile=圖D ,ellipse=no);


散佈圖、橢圓圖、迴歸線    散佈圖、橢圓圖
散佈圖 散佈圖、迴歸線

在【程式05】先重新產生一組新的模擬檔,更換了檔案名稱(height_2)和變項名稱(x_height、y_height)。

「option mprint」:執行巨集程式時初期都會開啟,觀察程式執行的過程。

巨集程式『scatter_plot』各參數的使用方法如下:

「data」:資料檔名稱
「x」:X軸所使用的變項
「x」:Y軸所使用的變項
「x_label」:圖形中X軸的名稱
「y_label」:圖形中Y軸的名稱
「outpath」:輸出的路徑
「outfile」:輸出檔案名
「ellipse」:是否繪製橢圓圖,YES:繪製(預設)、NO:不繪製。只要是是YES或空白,都是不繪製。
「reg」:是否繪製迴歸線,YES:繪製(預設)、NO:不繪製。

這隻巨集程式的修改只能算是初步的,不保證能在所有情境都可使用,需要有更多使用的經驗,才會讓程式越來越穩定。

SAS版本:9.4M3+

沒有留言:

張貼留言