This script uses a %procanno macro to modify an existing graph stored in an ODS document. It first extracts the data, graph template, and dynamic variables from the original graph. Then, it dynamically modifies the template to include an annotation instruction. Finally, it uses PROC SGRENDER to redraw the graph with the original data, the modified template, and an overlaid annotation dataset, allowing a watermark and a date to be added.
Data Analysis
Type : MIXTE
The script uses the SASHELP.CLASS table for the initial regression. It then internally creates an annotation dataset (anno), and a dataset (dp) by capturing the graphical output of PROC REG.
1 Code Block
PROC REG Data
Explanation : Performs a simple linear regression on sashelp.class. The ODS output is captured: the diagnostics panel is saved to a SAS dataset named 'dp', and the complete graphical object is stored in an ODS document named 'MyDoc' for later processing.
Explanation : Creates an annotation dataset ('anno') that defines two textual elements to overlay on a graph: a red date in the top right corner and a diagonal 'Confidential' watermark with high transparency.
Function = 'Text'; Label = 'Saturday, July 25, 2015';
4
Width = 100; x1 = 99; y1 = .1;
5
Anchor = 'Right'; TextColor = 'Red';
6
OUTPUT;
7
8
Label = 'Confidential - Do Not Distribute';
9
Width = 150; x1 = 50; y1 = 50; Anchor = 'Center';
10
Transparency = 0.8; TextSize = 40; Rotate = -45;
11
OUTPUT;
12
RUN;
3 Code Block
MACRO
Explanation : Defines a '%procanno' macro. It takes a dataset, a template name, an annotation dataset, and an ODS document as parameters. Its role is to extract the components of an existing graph (data, template, dynamic variables), modify its template to insert an annotation layer, then regenerate it with PROC SGRENDER by applying the annotations.
Copied!
%macro procanno(data=, template=, anno=anno, document=mydoc);
proc document name=&document;
ods exclude properties;
ods output properties=__p(where=(type='Graph'));
list / levels=all;
quit;
data _null_;
set __p;
call execute("proc document name=&document;");
call execute("ods exclude dynamics;");
call execute("ods output dynamics=__outdynam;");
call execute(catx(' ', "obdynam", path, ';'));
run;
proc template;
source &template/ file='temp.tmp';
quit;
data _null_;
infile 'temp.tmp';
input;
if _n_ = 1 then call execute('proc template;');
call execute(_infile_);
if _infile_ =: ' BeginGraph' then bg + 1;
if bg and index(_infile_, ';') then do;
bg = 0;
call execute('annotate;');
end;
run;
data _null_;
set __outdynam(where=(label1 ne '___NOBS___')) end=eof;
if nmiss(nvalue1) and cvalue1 = '.' then cvalue1 = ' ';
if _n_ = 1 then do;
call execute("proc sgrender data=&data sganno=&anno");
call execute("template=&template;");
call execute('dynamic');
end;
if cvalue1 ne ' ' then
call execute(catx(' ', label1, '=',
ifc(n(nvalue1), cvalue1, quote(trim(cvalue1)))));
if eof then call execute('; run;');
run;
proc template;
delete &template;
quit;
%mend;
Explanation : Calls the '%procanno' macro to apply the annotation process. It uses the 'dp' dataset (containing the graph data) and specifies the 'Stat.REG.Graphics.DiagnosticsPanel' template as the basis for reconstructing the annotated graph.
This material is provided "as is" by We Are Cas. There are no warranties, expressed or implied, as to merchantability or fitness for a particular purpose regarding the materials or code contained herein. We Are Cas is not responsible for errors in this material as it now exists or will exist, nor does We Are Cas provide technical support for it.
« his technique is the "nuclear option" for graph customization. It allows you to bypass the limitations of built-in procedure options, effectively turning SAS into a fully automated desktop publishing engine for statistical results. »
SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other countries. ® indicates USA registration. WeAreCAS is an independent community site and is not affiliated with SAS Institute Inc.
This site uses technical and analytical cookies to improve your experience.
Read more.