原文鏈接:http://tecdat.cn/?p=5179
在我們開始之前,讓我們更好地了解當您運行PROC SGPLOT以及BY語句和SG注釋數據集時會發生什么。這個例子為每個通過Sex運行PROC SGPLOT生成的圖形添加了一個注釋,單詞“Students”。
proc sort data=sashelp.class out=c; by sex; run; data anno1; retain x1 20 y1 85 function 'Text' dataspace 'GraphPercent' width 100; label = 'Students'; output; run; proc sgplot data=c sganno=anno1 tmplout='tmp1.tmp'; scatter y=weight x=height; by sex; run;


不需要TMPLOUT =選項。但是,它顯示了PROC SGPLOT編寫的用於制作圖形的模板。如果您真的想了解PROC SGPLOT的作用,您需要了解模板。它存儲在文件tmp1.tmp中,如下所示(添加縮進后)。
proc template; define statgraph sgplot; dynamic __BYLINE__; begingraph / collation=binary; EntryTitle __BYLINE__ / textattrs=(size=GraphLabelText:fontsize); layout overlay / yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split); ScatterPlot X=Height Y=Weight / subpixel=off primary=true LegendLabel="Weight" NAME="SCATTER"; DrawText "Students" / X=20 Y=85 WIDTH=100; endlayout; endgraph; end; run;
出於我們的目的,我想指出的是DRAWTEXT語句。它提供了注釋。雖然PROC SGRENDER接受SGANNO =數據集,但不是這個圖形的創建方式。相反,PROC SGPLOT讀取SG注釋數據集並將每一行轉換為GTL DRAW語句。
現在考慮SG注釋數據集,其具有與DATA =數據集中的BY變量匹配的BY變量。
data anno2; x1 = 20; y1 = 85; function = 'Text'; dataspace = 'GraphPercent'; width = 100; label = 'Female Students'; Sex = 'F'; output; label = 'Male Students'; Sex = 'M'; output; run;
如果您使用BY語句和SGANNO =選項運行PROC SGPLOT,則在兩個圖中都會同時獲得兩個注釋,這幾乎肯定不是您想要的。
proc sgplot data=c sganno=anno2 tmplout='tmp2.tmp'; scatter y=weight x=height; by sex; run;


這是文件tmp2.tmp,其中包含生成的GTL:
proc template; define statgraph sgplot; dynamic __BYLINE__; begingraph / collation=binary; EntryTitle __BYLINE__ / textattrs=(size=GraphLabelText:fontsize); layout overlay / yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split); ScatterPlot X=Height Y=Weight / subpixel=off primary=true LegendLabel="Weight" NAME="SCATTER"; DrawText "Female Students" / X=20 Y=85 WIDTH=100; DrawText "Male Students" / X=20 Y=85 WIDTH=100; endlayout; endgraph; end; run;
現在有兩個DRAWTEXT語句。兩者都是無條件使用的。因此,如果我們想在每個圖中使用不同的注釋,我們必須以其他方式處理這個問題。如果要為每個圖形添加不同的文本,則不需要SG注釋。您可以修改輸入數據集並在PROC SGPLOT中使用TEXT語句。
data c2; set c; by sex; if first.sex and sex eq 'F' then do; x1 = 51; y1 = 104; Label = 'Female'; end; else if first.sex and sex eq 'M' then do; x1 = 56; y1 = 140; Label = 'Male'; end; else call missing(label,x1,y1); run; proc sgplot data=c2; scatter y=weight x=height; text y=y1 x=x1 text=label; by sex; run;


使用這種方法以及TEXT和POLYGON語句可以做很多事情,而不需要SG注釋。盡管如此,SG注釋非常有用,與TEXT和POLYGON語句不同,它為您提供了各種坐標系。
接下來,我們將創建一個SG注釋數據集以及一個ID變量(名為ID),其值與BY變量Sex相匹配。
data anno3; x1 = 20; y1 = 85; function = 'Text'; dataspace = 'GraphPercent'; width = 100; label = 'Female Students'; id = 'F'; output; label = 'Male Students'; id = 'M'; output; run; 現在,PROC SGPLOT僅用於將模板寫入文件tmp3.tmp。 proc sgplot data=c tmplout='tmp3.tmp'; ods exclude sgplot; scatter y=weight x=height; by sex; run;
這是文件(不添加任何縮進)。
proc template; define statgraph sgplot; dynamic __BYLINE__; begingraph / collation=binary; EntryTitle __BYLINE__ / textattrs=(size=GraphLabelText:fontsize); layout overlay / yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split); ScatterPlot X=Height Y=Weight / subpixel=off primary=true LegendLabel="Weight" NAME="SCATTER"; endlayout; endgraph; end; run;
您可以使用DATA步驟編輯此模板並將其提交給SAS。下面的語句添加了一個PROC TEMPLATE語句,將模板名稱從sgplot更改為by,並添加動態變量和ANNOTATE語句。
data _null_; infile 'tmp3.tmp'; input; if _n_ eq 1 then call execute('proc template;'); _infile_ = tranwrd(_infile_, 'sgplot;', 'by;'); call execute(_infile_); if find(_infile_, 'layout overlay') then call execute('dynamic _byval_; annotate / id=_byval_;'); run;
您可以提交以下語句以查看已編輯的模板。
proc template; source by; quit;
接下來顯示編譯的模板。
define statgraph By; dynamic __BYLINE__ _byval_; begingraph / collation=binary; EntryTitle __BYLINE__ / textattrs=(size=GraphLabelText:fontsize); layout overlay / yaxisopts=(labelFitPolicy=Split) y2axisopts=( labelFitPolicy=Split); annotate / id=_BYVAL_; ScatterPlot X=HEIGHT Y=WEIGHT / subpixel=off primary=true LegendLabel= "Weight" NAME="SCATTER"; endlayout; endgraph; end;
請注意,編譯的模板與原始模板不完全匹配。特別是,DYNAMIC語句被組合在一起。使用PROC TEMPLATE查看模板的一個好處是模板很好地縮進。
請注意,動態變量_byval_與ID =值匹配。
現在,您可以使用PROC SGRENDER以及SGANNO =選項和BY語句來為每個圖形獲取單獨的注釋。
title; options nobyline; proc sgrender data=c template=by sganno=anno3; by sex; run; options byline;


替代方法要求您使用GTL編寫圖形模板,然后使用PROC SGRENDER。雖然這種PROC SGPLOT方法有更多步驟,但它更容易。在PROC SGPLOT中指定如何構建圖形比從頭開始編寫模板更容易。您將需要一個DATA步驟來修改該模板,但這並不難,因為您可以簡單地復制我的代碼。修改模板的DATA步驟中沒有特定於此示例的內容。