最近状原,出了幾張Table聋呢,參考代碼是用Gplot過程步輸出的。一般出圖颠区,我習慣GTL設(shè)置Template后削锰,使用Sgrender過程步進行調(diào)用。這次統(tǒng)計師要得比較急毕莱,我就先照著參考程序進行更新器贩。這篇文章用以梳理一下,這個過程中遇到的問題朋截。
看一下參考的圖形:
- 輸出的圖形是兩個PCHG變量的散點圖和回歸直線蛹稍;
- 涉及到的統(tǒng)計量有每個治療組的BigN、回歸直線的r方部服、每個象限的頻數(shù)占比唆姐;
- 兩組圖形是同排并列放置的。
這里就先不討論統(tǒng)計量的具體生成過程廓八,看到參考圖形的第一眼奉芦,我是想到用Template中的layout lattice
處理兩組圖形并列的問題。當前的任務(wù)跟參考的圖形有一點不同瘫想,參考圖形只需要輸出Month 36一個訪視圖形仗阅,而目前是需要輸出Month 12昌讲、Month 24国夜、Month 36三個訪視。因此短绸,并列的圖形上還需要加上訪視的信息车吹。
輸出3個訪視圖形,在Template中醋闭,我想到2個處理方法:
- 通過3個條件語句將同樣的圖形輸出3遍(這個可以通過宏程序來實現(xiàn)窄驹,以便簡化代碼);
- 在輸出圖形時使用By語句進行分組處理证逻。
以上是我在沒有看到參考程序時的想法乐埠,看了程序之后發(fā)現(xiàn),其實現(xiàn)思路跟我的有所不同囚企。
參考程序兩次調(diào)用gplot過程步丈咐,同時使用gout
選項將兩個試驗組的圖形輸出到同一個圖形目錄下。之后龙宏,使用greplay過程步重新調(diào)用這個圖形目錄下的圖形棵逊,并設(shè)置好圖形的展現(xiàn)屬性,輸出到RTF中银酗。程序的邏輯框架如下:
***Create figures and save figures in the graphics catalog - temp;
proc gplot data = anldata gout = temp ;
plot var1*var2;
where trt = "A";
run;
proc gplot data=data1 gout = temp ;
plot var1*var2;
where trt = "B";
run;
quit;
***Set figures display(設(shè)置調(diào)用圖形的4個角的坐標);
proc greplay nofs tc = tempcat;
tdef temp
1/llx = 6 lly=16 ulx=6 uly=90 urx=49 ury=90 lrx=49 lry=16
2/llx = 54 lly=16 ulx=54 uly=90 urx=97 ury=90 lrx=97 lry=16;
run;
***Display figures;
proc greplay nofs tc = tempcat igout = temp;
list igout;
template temp;
treplay 1:1 2:2;
delete _all_;
run;
quit;
之前辆影,我從沒有接觸過這樣的出圖設(shè)置徒像。我照著參考代碼的邏輯,也成功輸出一個組別的并列圖形蛙讥。但是目前的任務(wù)锯蛀,還需要輸出額外其他兩組的并列圖形,這3組圖形需要分別輸出到RTF文件的3個頁面中次慢。我嘗試了不短的時間谬墙,一下子沒辦法實現(xiàn),考慮到時間緊迫经备,我就改用GTL的方法拭抬,重寫程序。
回過頭看侵蒙,當時自己其實是可以用參考程序的方法造虎,粗略地輸出3組圖形的——將成功輸出的第一組地代碼,復(fù)制兩遍纷闺,篩選好對應(yīng)組別的數(shù)據(jù)算凿,進行輸出。
但是犁功,當時這個方法有兩個瑕疵氓轰,第一,每個組別的圖形上部需要加上組別的Label浸卦,直接將圖形輸出3遍無法處理這個問題署鸡;第二,參考代碼中的每個圖形中的統(tǒng)計量的輸出屬性都是單獨設(shè)置的限嫌,也就是說靴庆,參考這樣的代碼,我至少進行3*2*N種屬性設(shè)置(N為單獨一張圖形中統(tǒng)計量的個數(shù))怒医,這個過程太繁瑣了炉抒。于是,我選擇重寫代碼稚叹。
1. Graph Template Language (GTL)——重復(fù)輸出3次
1.1 處理原始數(shù)據(jù)
以SASHELP.CLASS數(shù)據(jù)集為例焰薄,分析變量取Height和Weight,演示圖形輸出扒袖。因為有多個訪視組塞茅,需要提前對數(shù)據(jù)處理,治療組變量就選用Sex僚稿。考慮到兩試驗分組并列輸出凡桥,在同一個Template語句中,需要根據(jù)分析的組別進行拆分分析變量蚀同。
***1. Get data from SASHELP.CLASS;
data class;
set sashelp.class(in = a)
sashelp.class(in = b)
sashelp.class(in = c);
**Create analysis visit for display;
if a then do;
avisit = "Month 12";
avisitn = 12;
end;
if b then do;
avisit = "Month 24";
avisitn = 24;
end;
if c then do;
avisit = "Month 36";
avisitn = 36;
end;
**Create analysis var;
if sex = "M" then do;
height_m = height;
weight_m = weight;
end;
if sex = "F" then do;
height_f = height;
weight_f = weight;
end;
run;
1.2 設(shè)置Template并輸出單個訪視的圖形
數(shù)據(jù)處理好后缅刽,開始Template的設(shè)置啊掏。使用的方法是,設(shè)置同一個Template衰猛,每個訪視分別調(diào)用一次迟蜜。
3個訪視的圖形輸出在同一個RTF文件中,每一個圖形都需要有各自的組別標志啡省,這個一般也有兩種方式進行實現(xiàn):
- 在Begingraph區(qū)域娜睛,使用
Entrytitle
語句;- 使用
Legenditem
語句新建一個文字類型的Legend卦睹,調(diào)用時設(shè)置為居中放置圖形外部 (手動實現(xiàn)Title的效果)畦戒。
在Template過程步中,圖形的并排輸出使用Layout Lattice
語句结序。該語句創(chuàng)建圖形網(wǎng)格障斋,使各個單元內(nèi)圖形輸出內(nèi)容自動對齊,方便比較徐鹤。這個任務(wù)需要輸出兩列垃环,在Layout Lattice
內(nèi)部進行各列圖形的設(shè)置。本次代碼中返敬,兩組并列圖形的設(shè)置完全相同遂庄。
***2. Create a macro for one avisit figure output;
%macro figure(avisitn = , label = );
**Create a Template;
proc template;
define statgraph plot;
begingraph;
entrytitle "&label";
layout lattice / columns = 2 ;
**Set column headers;
column2headers;
entry textattrs=(weight=bold size=9pt) "Male N = (xxx)";
entry textattrs=(weight=bold size=9pt) "Female N = (xxx)";
endcolumn2headers;
**Column 1 content;
layout overlay/ xaxisopts=(label="Weight") yaxisopts=(label="Height") ;
*Plots of scatterplot and regression;
scatterplot x=weight_m y=height_m / markerattrs=(size = 5pt color=blue symbol=CircleFilled);
regressionplot x=weight_m y=height_m / lineattrs=(color=blue);
endlayout;
**Column 2 content;
layout overlay/ xaxisopts=(label="Weight") yaxisopts=(label="Height") ;
*Plots of scatterplot and regression;
scatterplot x=weight_f y=height_f / markerattrs=(size = 5pt color=blue symbol=CircleFilled);
regressionplot x=weight_f y=height_f / lineattrs=(color=blue);
endlayout;
endlayout;
endgraph;
end;
run;
**Render a Template;
proc sgrender data = class template=plot;
where avisitn = &avisitn.;
run;
%mend figure;
1.3 輸出3個訪視的圖形
針對一個訪視的圖形輸出后,根據(jù)訪視組別重復(fù)3次就可以輸出劲赠。輸出時設(shè)置需要的Title 和Footnotes涛目,以及對應(yīng)的輸出路徑。
***3. Run macros to creeate figures for 3 avisits;
title "Template for Output";
footnote "Data Generated: &sysdate &systime";
ods rtf file = "&out_dir.test.rtf" nogtitle bodytitle;
ods listing close;
ods select all;
%figure(avisitn = 12, label =Month 12);
%figure(avisitn = 24, label =Month 24);
%figure(avisitn = 36, label =Month 36);
ods rtf close;
ods graphics off;
ods listing;
2. Graph Template Language (GTL)——使用By 語句
2.1 處理原始數(shù)據(jù)
與1.1內(nèi)容完全相同经磅,參照前面內(nèi)容泌绣。
2.2 設(shè)置Template并按訪視變量分組輸出圖形
跟1.2相比钮追,這一部分代碼的改動也不算大预厌。
在Sgplot
過程步中使用By語句,就不需要單獨篩選某個訪視元媚。1.2中轧叽,重復(fù)調(diào)用宏程序3次,改變每次宏參數(shù)的值 (&label
)刊棕,能夠通過entrytitle
語句分別輸出3個訪視組別的標志內(nèi)容炭晒。使用By語句之后,只調(diào)用一次宏程序甥角,如果用宏參數(shù)來控制輸出組別的標志內(nèi)容网严,只能輸出一個值,顯然這不能滿足三個訪視的輸出嗤无。
通過控制宏參數(shù)來輸出組別的標志內(nèi)容震束,參考如下:(這里直接將entrytitle
語句的輸出內(nèi)容設(shè)置為“Label”)
***2. Create a macro for one avisit figure output;
%macro figure;
**Create a Template;
proc template;
define statgraph plot;
begingraph;
entrytitle "label";
layout lattice / columns = 2 ;
**Set column headers;
column2headers;
entry textattrs=(weight=bold size=9pt) "Male N = (xxx)";
entry textattrs=(weight=bold size=9pt) "Female N = (xxx)";
endcolumn2headers;
**Column 1 content;
layout overlay/ xaxisopts=(label="Weight") yaxisopts=(label="Height") ;
*Plots of scatterplot and regression;
scatterplot x=weight_m y=height_m / markerattrs=(size = 5pt color=blue symbol=CircleFilled);
regressionplot x=weight_m y=height_m / lineattrs=(color=blue);
endlayout;
**Column 2 content;
layout overlay/ xaxisopts=(label="Weight") yaxisopts=(label="Height") ;
*Plots of scatterplot and regression;
scatterplot x=weight_f y=height_f / markerattrs=(size = 5pt color=blue symbol=CircleFilled);
regressionplot x=weight_f y=height_f / lineattrs=(color=blue);
endlayout;
endlayout;
endgraph;
end;
run;
**Render a Template;
proc sgrender data = class template=plot;
where avisitn = &avisitn.;
run;
%mend figure;
title "Template for Output";
footnote "Data Generated: &sysdate &systime";
ods rtf file = "&out_dir.test.rtf" nogtitle bodytitle;
ods listing close;
ods select all;
%figure;
ods rtf close;
ods graphics off;
ods listing;
程序運行后怜庸,我們可以看到By語句會自動在圖形之上,輸出具體對應(yīng)這個圖形的亞組垢村。顯然割疾,avisitn=12
是不符合輸出要求的,對于此嘉栓,可以可以通過控制分組變量的Label和Format來更新此處輸出的內(nèi)容宏榕,這一部分我在前面文章中有過介紹,讀者可以參考SAS編程:特殊字符-空格的應(yīng)用 侵佃。
不過麻昼,這種方法輸出的效果調(diào)整也只能輸出成類似Analysis Visit = Month 12。這里需要與統(tǒng)計師進行溝通馋辈,如果統(tǒng)計師不能介紹這樣的輸出涌献,并且鑒定的要求輸出成“Month 12”,那只能另尋其他方法了首有。
以宏參數(shù)控制entrytitle
語句輸出燕垃,會使3個訪視輸出結(jié)果相同,并且也會與前面By變量的顯示沖突井联。所以卜壕,使用By語句是需要移除entrytitle
語句的。
結(jié)語:
這篇文章介紹了GTL語言輸出分組并列的Figure的方法烙常,更細一步講轴捎,是介紹GTL語言輸出分組Figure的方法(重復(fù)輸出或使用By語句),以及介紹GTL語言輸出并列Figure的方法(layout lattice
語句)蚕脏。
關(guān)于具體的坐標軸的屬性設(shè)置侦副,文章并沒有介紹。這一塊屬性的調(diào)試也會花費不少時間驼鞭。具體的語法介紹秦驯,讀者可以參考SAS的官方文檔:SAS Help Center: SAS 9.4 Graph Template Language: Reference, Fifth Edition。
感謝閱讀挣棕!若有疑問译隘,歡迎評論區(qū)交流!