BookmarkSubscribeRSS Feed

A SAS template style that follows Stephen Few's style guidelines

Started ‎11-01-2016 by
Modified ‎11-01-2016 by
Views 4,754

I've just  got my hands on Stephen Few's "Show me the numbers" and wanted to implement to most basics advice automatically by creating a template/style.  I created a PROC TEMPLATE program that creates such a style; here are some samples of the result.

 

fewtable.png

 

fewplot.png

 

It's not perfect, but here's my template program, along with examples of use with proc report and proc sgplot.

 

 


%macro hex2(n);
  %local digits n1 n2;
  %let digits = 0123456789ABCDEF;
  %let n1 = %substr(&digits, &n / 16 + 1, 1);
  %let n2 = %substr(&digits, &n - &n / 16 * 16 + 1, 1);
  &n1&n2
%mend hex2;
 
/* convert RGB triplet (r,g,b) to SAS color in hexadecimal. 
   The r, g, and b parameters are integers in the range 0--255 */
%macro RGB(r,g,b);
  %cmpres(CX%hex2(&r)%hex2(&g)%hex2(&b))
%mend RGB;

*** light is used for large data objects, such as a bar or box;
%let lightgrey = %rgb(140,140,140);
%let lightblue = %rgb(136,189,230);
%let lightorange = %rgb(251,178,88);
%let lightgreen  = %rgb(144,205,151);
%let lightpink  = %rgb(246,170,201);
%let lightbrown = %rgb(191,165,84);
%let lightpurple = %rgb(188,153,199);
%let lightyellow = %rgb(237,221,70);
%let lightred  = %rgb(240,126,110);
*** medium is used for small data objects such as data points and lines;
%let mediumgrey = %rgb(77,77,77);
%let mediumblue = %rgb(93,165,218);
%let mediumorange = %rgb(250,164,58);
%let mediumgreen  = %rgb(96,189,104);
%let mediumpink  = %rgb(241,124,176);
%let mediumbrown = %rgb(178,145,47);
%let mediumpurple = %rgb(178,118,178);
%let mediumyellow = %rgb(222,207,63);
%let mediumred  = %rgb(241,88,84);

*** dark and bright highlighter is used for objects, such as a single bar;
%let darkgrey = %rgb(0,0,0);
%let darkblue = %rgb(38,93,171);
%let darkorange = %rgb(223,92,36);
%let darkgreen  = %rgb(5,151,72);
%let darkpink  = %rgb(229,18,111);
%let darkbrown = %rgb(157,114,42);
%let darkpurple = %rgb(123,58,150);
%let darkyellow = %rgb(199,180,46);
%let darkred  = %rgb(203,32,39);

proc template;
 define style Styles.Custom;
 parent = Styles.RTF;

 replace fonts /
 'TitleFont' = ("Tahoma",14pt,Bold) /* Titles from TITLE statements */
 'TitleFont2' = ("Tahoma",14pt,Bold) /* Procedure titles ("The _____ Procedure")*/
 'StrongFont' = ("Tahoma",10pt,Bold)
 'EmphasisFont' = ("Tahoma",10pt,Italic)
 'headingEmphasisFont' = ("Tahoma",10pt,Italic)
 'headingFont' = ("Tahoma",10pt) /* Table column and row headings */
 'docFont' = ("Tahoma",10pt) /* Data in table cells */
 'footFont' = ("Tahoma",8pt) /* Footnotes from FOOTNOTE statements */
 'FixedEmphasisFont' = ("Courier",10pt,Italic)
 'FixedStrongFont' = ("Courier",10pt,Bold)
 'FixedHeadingFont' = ("Courier",10pt,Bold)
 'BatchFixedFont' = ("Courier",7pt)
 'FixedFont' = ("Courier",10pt);

replace color_list /
 'link' = &darkblue. /* links */
 'bgH' = white /* row and column header background */
 'fg' = black /* text color */
 'bg' = white; /* page background color */;

replace Body from Document /
 bottommargin = 0.25in
 topmargin = 0.25in
 rightmargin = 0.25in
 leftmargin = 0.25in;

replace Table from Output /
 frame = void /* outside borders: void, box, above/below, vsides/hsides, lhs/rhs */
 rules = groups /* internal borders: none, all, cols, rows, groups */
 cellpadding = 3pt /* the space between table cell contents and the cell border */
 cellspacing = 0pt /* the space between table cells, allows background to show */
 borderwidth = 2pt /* the width of the borders and rules */;

* Leave code below this line alone ;
		style SystemFooter from SystemFooter /
 				font = fonts("footFont");
  * mon code a moi;
replace GraphFonts /
	'GraphDataFont'=("Tahoma",10pt) 
	'GraphUnicodeFont'=("Tahoma",10pt) 
	'GraphValueFont'=("Tahoma",10pt) 
	'GraphLabelFont'=("Tahoma",10pt) 
	'GraphLabel2Font'=("Tahoma",10pt) 
	'GraphFootnoteFont'=("Tahoma",8pt) 
	'GraphTitleFont'=("Tahoma",14pt) 
	'GraphTitle1Font'=("Tahoma",14pt) 
	'GraphAnnoFont'=("Tahoma",10pt) 
;

replace  colors
/*      "Abstract colors used in the default style" *//
      'headerfgemph' = color_list('fg')
      'headerbgemph' = color_list('bgH')
      'headerfgstrong' = color_list('fg')
      'headerbgstrong' = color_list('bgH')
      'headerfg' = color_list('fg')
      'headerbg' = color_list('bgH')
      'datafgemph' = color_list('fg')
      'databgemph' = color_list('bg')
      'datafgstrong' = color_list('fg')
      'databgstrong' = color_list('bg')
      'datafg' = color_list('fg')
      'databg' = color_list('bg')
      'batchbg' = color_list('bg')
      'batchfg' = color_list('fg')
      'tableborder' =&mediumgrey.
      'tablebg' = color_list('bg')
      'notefg' = color_list('fg')
      'notebg' = color_list('bg')
      'bylinefg' = color_list('fg')
      'bylinebg' = color_list('bg')
      'captionfg' = color_list('fg')
      'captionbg' = color_list('bg')
      'proctitlefg' = color_list('fg')
      'proctitlebg' = color_list('bg')
      'titlefg' = color_list('fg')
      'titlebg' = color_list('bg')
      'systitlefg' = color_list('fg')
      'systitlebg' = color_list('bg')
      'Conentryfg' = color_list('fg')
      'Confolderfg' = color_list('fg')
      'Contitlefg' = color_list('fg')
      'link2' = color_list('link')
      'link1' = color_list('link')
      'contentfg' = color_list('fg')
      'contentbg' = color_list('bg')
      'docfg' = color_list('fg')
      'docbg' = color_list('bg');
replace GraphColors /
      /*"Abstract colors used in graph styles" */
      'ginsetheader' = colors('docbg')
      'ginset' = white
      'greferencelines' = &mediumgrey.
      'gheader' = colors('docbg')
      'gtext' = &mediumgrey.
      'glabel' = &mediumgrey.
      'gborderlines' = &mediumgrey.
      'goutlines' = &mediumgrey.
      'ggrid' = &lightgrey.
      'gaxis' = &lightgrey.
      'gshadow' = &lightgrey.
      'glegend' = white
      'gfloor' = white
      'gwalls' = _undef_
                 
      'gcdata1' = &mediumblue.
			'gcdata2' = &mediumorange.
			'gcdata3' = &mediumgreen.
			'gcdata4' = &mediumpink.
			'gcdata5' = &mediumbrown.
			'gcdata6' = &mediumpurple.
			'gcdata7' = &mediumyellow.
			'gcdata8' = &mediumred.
			'gcdata9' = &mediumgrey.
			'gcdata10' = &darkblue.
			'gcdata11' = &darkorange.
			'gcdata12' = &darkred.

      'gdata1' = &mediumgrey.
			'gdata2' = &mediumgrey.
			'gdata3' = &mediumgrey.
			'gdata4' = &mediumgrey.
			'gdata5' = &mediumgrey.
      'gdata6' = &mediumgrey.
      'gdata7' = &mediumgrey.
      'gdata8' = &mediumgrey.
      'gdata9' = &mediumgrey.
      'gdata10' = &mediumgrey.
      'gdata11' = &mediumgrey.
      'gdata12' = &mediumgrey. 

			'gcmiss' = &lightgrey.
      'gmiss' = &lightgrey.
      'gablock' = cxF1F0F6
      'gblock' = cxD7DFEF
      'gcclipping' = cxDC531F
      'gclipping' = cxE7774F
      'gcstars' = &mediumgrey.
      'gstars' = cxB9CFE7
      'gcruntest' = cxBF4D4D
      'gruntest' = cxCAE3FF
      'gccontrollim' = cxBFC7D9
      'gcontrollim' = cxE6F2FF
      'gcerror' = &mediumgrey.
      'gerror' = cxB9CFE7
      'gcpredictlim' = cx003178
      'gpredictlim' = cxB9CFE7
      'gcpredict' = cx003178
      'gpredict' = cx003178
      'gcconfidence2' = cx003178
      'gcconfidence' = cx003178
      'gconfidence2' = cxB9CFE7
      'gconfidence' = cxB9CFE7
      'gcfit2' = cx003178
      'gcfit' = cx003178
      'gfit2' = cx003178
      'gfit' = cx003178
      'gcoutlier' = &mediumgrey.
      'goutlier' = cxB9CFE7
      'gcdata' = &mediumgrey.
      'gdata' = cxB9CFE7
    

			'gconramp3cend' = cxFF0000
      'gconramp3cneutral' = cxFF00FF
      'gconramp3cstart' = cx0000FF
      'gramp3cend' = cxDD6060
      'gramp3cneutral' = white
      'gramp3cstart' = cx6497EB

			'gconramp2cend' = cx6497EB
      'gconramp2cstart' = white
      'gramp2cend' = cx5E528B
      'gramp2cstart' = cxEDEBF6

;
      class graphwalls / 
            	frameborder=off;
      class graphbackground / 
            	color=white;

    	style GraphData1 from GraphData1 /linestyle=1  markersymbol = "circle";
    	style GraphData2 from GraphData2 /linestyle=1  markersymbol = "circle";
    	style GraphData3 from GraphData3 /linestyle=1  markersymbol = "circle";
    	style GraphData4 from GraphData4 /linestyle=1  markersymbol = "circle";
    	style GraphData5 from GraphData5 /linestyle=1  markersymbol = "circle";
			style GraphData6 from GraphData6 /linestyle=1  markersymbol = "circle";
			style GraphData7 from GraphData7 /linestyle=1  markersymbol = "circle";
			style GraphData8 from GraphData8 /linestyle=1  markersymbol = "circle";
			style GraphData9 from GraphData9 /linestyle=1  markersymbol = "circle";
			style GraphData10 from GraphData10 /linestyle=1  markersymbol = "circle";
			style GraphData11 from GraphData11 /linestyle=1  markersymbol = "circle";
			style GraphData12 from GraphData12 /linestyle=1 markersymbol = "circle";

			style GraphBorderLines from GraphBorderLines / 
				LineThickness=0; 

		style GraphBackground / transparency=1  ;	
end;
run; 

/* Sample program that shows the output */


%let very_light_grey=E2EDF4;

ods rtf file="c:\temp\report.rtf"  style=styles.custom;
OPTIONS NODATE NONUMBER;
ods escapechar = '^'; 
title1  
 	j=c "Title" ;
title2 
	j=c "Subtitle";
*note : the trick for the header columns spanned from Beyond the Basics: Advanced PROC REPORT Tips and Tricks ";

footnote1 j=l "Footnote1";
footnote2 j=l "Footnote2";


proc sort data= sashelp.class out=temp;; by sex height weight;
run;

data temp;
set temp;
by sex;
if first.sex then sex2= sex;
else sex2="";
obs=_n_;
weight_cat= floor(weight/10)*10;
run;

proc report data=temp ls=120 ps=40 nowd 
	split="*"
	style(report)=
		[]
	style(header)=
		[just=l]; 

column 
	obs
	sex2
	name
	("^S={just=c borderbottomcolor=&lightgrey.} Metrics^{super 1}" height weight )
	row_color
;
define obs /display noprint;
define sex2/display  "Sex" style(header)=[just=l borderbottomcolor=&lightgrey.] style(column)=[just=l];
define name /display "Name" style(header)=[just=l  borderbottomcolor=&lightgrey.] style(column)=[just=l];
define height/display  "Height" format =5.1 style(header)=[just=r borderbottomcolor=&lightgrey.] style(column)=[just=r];
define weight /display "Weight^{super 2}" format =5.0 style(header)=[just=r borderbottomcolor=&lightgrey.] style(column)=[just=r ] format=16.;
define row_color  /computed noprint;
  
compute row_color;
		if mod(obs,2)=1 then call define (_row_,"style","style=[background=#&very_light_grey.]");
endcomp;

run;
quit;

ods rtf text=
	"^S={fontsize = 8pt color=&lightgrey.}  ^{newline}
	Notes: ^{newline}
	1. Some note about the metrics. ^{newline}
	2. Some note about the weight."
;
ods graphics / reset=all border=off width=6in height=4in;

proc sgplot data= temp;
scatter x=weight y=height /group=sex;
run;

proc sql;
create table for_graph as
select distinct sex, weight_cat, count(*) as count
from temp
group by sex,weight_cat
;
quit;

data for_graph3;
set for_graph;
by sex;
if last.sex then 		datalabel=sex;

run;

proc format ;

value weightcatf
50="50-60"
60="60-70"
70="70-80"
80="80-90"
90="90-100"
100="100-110"
110="110-120"
120="120-130"
130="130-140"
140="140-150"
150="150-160"
;
run;

proc sgplot data=for_graph3 noautolegend;
series x=weight_cat y=count /group=sex datalabel=datalabel;
yaxis values=(0 to 4 by 1) label="Count";
xaxis values=(50 to 150 by 10) label ="Weight category";
title "Count by sex and weight category";
format weight_cat weightcatf.;
run; 
title;

ods rtf close;

 

 

Thanks to @Reeza who has also shared the program on GitHub

  https://gist.github.com/statgeek/9845cc3d26e4c35e01a2

 

 

Comments

I get warnings in 9.4 along the lines of:

WARNING: Could not locate style reference 'Custom.GraphFonts("NodeLinkLabelFont")'.

 

 

Here is a copied version for people with OCD, with better code alignment:

 


/* Convert decimal RGB triplet (r,g,b) to hexadecimal SAS color.
   The r, g, and b parameters are integers in the range 0-255 */
%macro RGB(r,g,b);
 cx%sysfunc(putn(&r.,hex2.))%sysfunc(putn(&g.,hex2.))%sysfunc(putn(&b.,hex2.))
%mend RGB;

*** light is used for large data objects, such as a bar or box;
%let lightgrey    = %rgb(140,140,140);
%let lightblue    = %rgb(136,189,230);
%let lightorange  = %rgb(251,178, 88);
%let lightgreen   = %rgb(144,205,151);
%let lightpink    = %rgb(246,170,201);
%let lightbrown   = %rgb(191,165, 84);
%let lightpurple  = %rgb(188,153,199);
%let lightyellow  = %rgb(237,221, 70);
%let lightred     = %rgb(240,126,110);
*** medium is used for small data objects such as data points and lines;
%let mediumgrey   = %rgb( 77, 77, 77);
%let mediumblue   = %rgb( 93,165,218);
%let mediumorange = %rgb(250,164, 58);
%let mediumgreen  = %rgb( 96,189,104);
%let mediumpink   = %rgb(241,124,176);
%let mediumbrown  = %rgb(178,145, 47);
%let mediumpurple = %rgb(178,118,178);
%let mediumyellow = %rgb(222,207, 63);
%let mediumred    = %rgb(241, 88, 84);

*** dark and bright highlighter is used for objects, such as a single bar;
%let darkgrey     = %rgb(  0,  0,  0);
%let darkblue     = %rgb( 38, 93,171);
%let darkorange   = %rgb(223, 92, 36);
%let darkgreen    = %rgb(  5,151, 72);
%let darkpink     = %rgb(229, 18,111);
%let darkbrown    = %rgb(157,114, 42);
%let darkpurple   = %rgb(123, 58,150);
%let darkyellow   = %rgb(199,180, 46);
%let darkred      = %rgb(203, 32, 39);

proc template;
 define style Styles.Custom;
 parent = Styles.RTF;

 replace fonts /
 'TitleFont'           = ("Tahoma" ,14pt,Bold) /* Titles from TITLE statements         */
 'TitleFont2'          = ("Tahoma" ,14pt,Bold) /* Procedure title: The _____ Procedure */
 'StrongFont'          = ("Tahoma" ,10pt,Bold)
 'EmphasisFont'        = ("Tahoma" ,10pt,Italic)
 'headingEmphasisFont' = ("Tahoma" ,10pt,Italic)
 'headingFont'         = ("Tahoma" ,10pt)      /* Table column and row headings        */
 'docFont'             = ("Tahoma" ,10pt)      /* Data in table cells                  */
 'footFont'            = ("Tahoma" , 8pt)      /* Footnotes from FOOTNOTE statements   */
 'FixedEmphasisFont'   = ("Courier",10pt,Italic)
 'FixedStrongFont'     = ("Courier",10pt,Bold)
 'FixedHeadingFont'    = ("Courier",10pt,Bold)
 'BatchFixedFont'      = ("Courier",7pt)
 'FixedFont'           = ("Courier",10pt);

 replace color_list /
 'link' = &darkblue. /* links                            */
 'bgH'  = white      /* row and column header background */
 'fg'   = black      /* text color                       */
 'bg'   = white;     /* page background color            */;

 replace Body from Document /
 bottommargin = 0.25in
 topmargin    = 0.25in
 rightmargin  = 0.25in
 leftmargin   = 0.25in;

 replace Table from Output /
 frame       = void   /* outside borders: void, box, above/below, vsides/hsides, lhs/rhs */
 rules       = groups /* internal borders: none, all, cols, rows, groups                 */
 cellpadding = 3pt    /* the space between table cell contents and the cell border       */
 cellspacing = 0pt    /* the space between table cells, allows background to show        */
 borderwidth = 2pt    /* the width of the borders and rules                              */;

 style SystemFooter from SystemFooter /
 font = fonts("footFont");

 replace GraphFonts /
 'GraphDataFont'    =("Tahoma",10pt) 
 'GraphUnicodeFont' =("Tahoma",10pt) 
 'GraphValueFont'   =("Tahoma",10pt) 
 'GraphLabelFont'   =("Tahoma",10pt) 
 'GraphLabel2Font'  =("Tahoma",10pt) 
 'GraphFootnoteFont'=("Tahoma",8pt) 
 'GraphTitleFont'   =("Tahoma",14pt) 
 'GraphTitle1Font'  =("Tahoma",14pt) 
 'GraphAnnoFont'    =("Tahoma",10pt);

 replace  colors /               /* Abstract colors used in the default style */
 'headerfgemph'   = color_list('fg')
 'headerbgemph'   = color_list('bgH')
 'headerfgstrong' = color_list('fg')
 'headerbgstrong' = color_list('bgH')
 'headerfg'       = color_list('fg')
 'headerbg'       = color_list('bgH')
 'datafgemph'     = color_list('fg')
 'databgemph'     = color_list('bg')
 'datafgstrong'   = color_list('fg')
 'databgstrong'   = color_list('bg')
 'datafg'         = color_list('fg')
 'databg'         = color_list('bg')
 'batchbg'        = color_list('bg')
 'batchfg'        = color_list('fg')
 'tableborder'    = &mediumgrey.
 'tablebg'        = color_list('bg')
 'notefg'         = color_list('fg')
 'notebg'         = color_list('bg')
 'bylinefg'       = color_list('fg')
 'bylinebg'       = color_list('bg')
 'captionfg'      = color_list('fg')
 'captionbg'      = color_list('bg')
 'proctitlefg'    = color_list('fg')
 'proctitlebg'    = color_list('bg')
 'titlefg'        = color_list('fg')
 'titlebg'        = color_list('bg')
 'systitlefg'     = color_list('fg')
 'systitlebg'     = color_list('bg')
 'Conentryfg'     = color_list('fg')
 'Confolderfg'    = color_list('fg')
 'Contitlefg'     = color_list('fg')
 'link2'          = color_list('link')
 'link1'          = color_list('link')
 'contentfg'      = color_list('fg')
 'contentbg'      = color_list('bg')
 'docfg'          = color_list('fg')
 'docbg'          = color_list('bg');

 replace GraphColors /    /* Abstract colors used in graph styles */
 'ginsetheader'     = colors('docbg')
 'ginset'           = white
 'greferencelines'  = &mediumgrey.
 'gheader'          = colors('docbg')
 'gtext'            = &mediumgrey.
 'glabel'           = &mediumgrey.
 'gborderlines'     = &mediumgrey.
 'goutlines'        = &mediumgrey.
 'ggrid'            = &lightgrey.
 'gaxis'            = &lightgrey.
 'gshadow'          = &lightgrey.
 'glegend'          = white
 'gfloor'           = white
 'gwalls'           = _undef_
            
 'gcdata1'          = &mediumblue.
 'gcdata2'          = &mediumorange.
 'gcdata3'          = &mediumgreen.
 'gcdata4'          = &mediumpink.
 'gcdata5'          = &mediumbrown.
 'gcdata6'          = &mediumpurple.
 'gcdata7'          = &mediumyellow.
 'gcdata8'          = &mediumred.
 'gcdata9'          = &mediumgrey.
 'gcdata10'         = &darkblue.
 'gcdata11'         = &darkorange.
 'gcdata12'         = &darkred.

 'gdata1'           = &mediumgrey.
 'gdata2'           = &mediumgrey.
 'gdata3'           = &mediumgrey.
 'gdata4'           = &mediumgrey.
 'gdata5'           = &mediumgrey.
 'gdata6'           = &mediumgrey.
 'gdata7'           = &mediumgrey.
 'gdata8'           = &mediumgrey.
 'gdata9'           = &mediumgrey.
 'gdata10'          = &mediumgrey.
 'gdata11'          = &mediumgrey.
 'gdata12'          = &mediumgrey. 

 'gcmiss'           = &lightgrey.
 'gmiss'            = &lightgrey.
 'gablock'          = cxF1F0F6
 'gblock'           = cxD7DFEF
 'gcclipping'       = cxDC531F
 'gclipping'        = cxE7774F
 'gcstars'          = &mediumgrey.
 'gstars'           = cxB9CFE7
 'gcruntest'        = cxBF4D4D
 'gruntest'         = cxCAE3FF
 'gccontrollim'     = cxBFC7D9
 'gcontrollim'      = cxE6F2FF
 'gcerror'          = &mediumgrey.
 'gerror'           = cxB9CFE7
 'gcpredictlim'     = cx003178
 'gpredictlim'      = cxB9CFE7
 'gcpredict'        = cx003178
 'gpredict'         = cx003178
 'gcconfidence2'    = cx003178
 'gcconfidence'     = cx003178
 'gconfidence2'     = cxB9CFE7
 'gconfidence'      = cxB9CFE7
 'gcfit2'           = cx003178
 'gcfit'            = cx003178
 'gfit2'            = cx003178
 'gfit'             = cx003178
 'gcoutlier'        = &mediumgrey.
 'goutlier'         = cxB9CFE7
 'gcdata'           = &mediumgrey.
 'gdata'            = cxB9CFE7

 'gconramp3cend'    = cxFF0000
 'gconramp3cneutral'= cxFF00FF
 'gconramp3cstart'  = cx0000FF
 'gramp3cend'       = cxDD6060
 'gramp3cneutral'   = white
 'gramp3cstart'     = cx6497EB

 'gconramp2cend'    = cx6497EB
 'gconramp2cstart'  = white
 'gramp2cend'       = cx5E528B
 'gramp2cstart'     = cxEDEBF6;

 class graphwalls / 
 frameborder=off;

 class graphbackground / 
 color=white;

 style GraphData1  from GraphData1  /linestyle=1 markersymbol = "circle";
 style GraphData2  from GraphData2  /linestyle=1 markersymbol = "circle";
 style GraphData3  from GraphData3  /linestyle=1 markersymbol = "circle";
 style GraphData4  from GraphData4  /linestyle=1 markersymbol = "circle";
 style GraphData5  from GraphData5  /linestyle=1 markersymbol = "circle";
 style GraphData6  from GraphData6  /linestyle=1 markersymbol = "circle";
 style GraphData7  from GraphData7  /linestyle=1 markersymbol = "circle";
 style GraphData8  from GraphData8  /linestyle=1 markersymbol = "circle";
 style GraphData9  from GraphData9  /linestyle=1 markersymbol = "circle";
 style GraphData10 from GraphData10 /linestyle=1 markersymbol = "circle";
 style GraphData11 from GraphData11 /linestyle=1 markersymbol = "circle";
 style GraphData12 from GraphData12 /linestyle=1 markersymbol = "circle";

 style GraphBorderLines from GraphBorderLines / 
 LineThickness=0; 

 style GraphBackground / 
 transparency=1  ;  

end;
run; 

/* Sample program that shows the output */

%let very_light_grey=E2EDF4;

*ods rtf file="c:\temp\report.rtf"  style=styles.custom;
ods rtf file="%sysfunc(pathname(work))\report.rtf"  style=styles.custom;
options nodate nonumber;
ods escapechar = '^'; 
title1 j=c "Title" ;
title2 j=c "Subtitle";
*note : the trick for the header columns spanned from Beyond the Basics: Advanced PROC REPORT Tips and Tricks ";
footnote1 j=l "Footnote1";
footnote2 j=l "Footnote2";

proc sort data= SASHELP.CLASS out=TEMP; 
 by SEX HEIGHT WEIGHT;
run;

data TEMP;
 set TEMP;
 by SEX;
 if first.SEX then SEX2= SEX;
 else SEX2=' ';
 OBS=_N_;
 WEIGHT_CAT = floor(WEIGHT/10)*10;
run;

proc report data         = TEMP 
            ls           = 120 
            ps           = 40  
            split        = "*"
            style(report)= []
            style(header)= [just=l] 
            nowd;

 column 
  OBS
  SEX2
  NAME 
  ("^S={just=c borderbottomcolor=&lightgrey.} Metrics^{super 1}" HEIGHT WEIGHT )
  ROW_COLOR;

 define OBS      /display noprint;

 define SEX2     /display "Sex" style(header)=[just=l borderbottomcolor=&lightgrey.] 
                                style(column)=[just=l ];

 define NAME     /display "Name" style(header)=[just=l  borderbottomcolor=&lightgrey.]
                                 style(column)=[just=l ];

 define HEIGHT   /display "Height" format =5.1 
                                   style(header)=[just=r borderbottomcolor=&lightgrey.] 
                                   style(column)=[just=r ];

 define WEIGHT   /display "Weight^{super 2}" format =5.0 
                                             style(header)=[just=r borderbottomcolor=&lightgrey.]
                                             style(column)=[just=r ] ;

 define ROW_COLOR/computed noprint;
  
 compute ROW_COLOR;
  if mod(OBS,2)=1 then call define (_row_,"style","style=[background=#&very_light_grey.]");
 endcomp;

run;
quit;

ods rtf text=
  "^S={fontsize = 8pt color=&lightgrey.}  ^{newline}
  Notes: ^{newline}
  1. Some note about the metrics. ^{newline}
  2. Some note about the weight."
;
ods graphics / reset=all border=off width=6in height=4in;

proc sgplot data= TEMP;
 scatter x=WEIGHT y=HEIGHT /group=SEX;
run;

proc sql;
 create table FOR_GRAPH as
 select distinct SEX, WEIGHT_CAT, count(*) as COUNT
 from TEMP
 group by SEX, WEIGHT_CAT
;
quit;

data FOR_GRAPH3;
 set FOR_GRAPH;
 by SEX;
 if last.SEX then DATALABEL=SEX;
run;

proc format ;
  value weightcatf
   50= "50-60"
   60= "60-70"
   70= "70-80"
   80= "80-90"
   90= "90-100"
  100="100-110"
  110="110-120"
  120="120-130"
  130="130-140"
  140="140-150"
  150="150-160";
run;

proc sgplot data=FOR_GRAPH3 noautolegend;
  series x=WEIGHT_CAT y=COUNT /group=SEX datalabel=DATALABEL;
  yaxis values=( 0 to   4 by  1) label ="Count";
  xaxis values=(50 to 150 by 10) label ="Weight category";
  title "Count by sex and weight category";
  format WEIGHT_CAT weightcatf.;
run; 
title;

ods rtf close;

 

 

Hi @ChrisNZ - I think this is because the GraphFonts and GraphColors "target" elements have expanded in SAS 9.4 maintenance releases (especially 9.4m3), and this example does not include them.  When you use the REPLACE keyword, those font/color definitions are dropped and if the parent template references them, then the previous values are dropped.   You can use the CLASS keyword instead, as in:

 

class GraphFonts /
	'GraphDataFont'=("Tahoma",10pt) 
	'GraphUnicodeFont'=("Tahoma",10pt) 
	'GraphValueFont'=("Tahoma",10pt) 
	'GraphLabelFont'=("Tahoma",10pt) 
	'GraphLabel2Font'=("Tahoma",10pt) 
	'GraphFootnoteFont'=("Tahoma",8pt) 
	'GraphTitleFont'=("Tahoma",14pt) 
	'GraphTitle1Font'=("Tahoma",14pt) 
	'GraphAnnoFont'=("Tahoma",10pt)
;

That's my guess -- I'm going to ping @DanH_sas to see if there are any downsides to that.

@ChrisHemedinger is correct. In SAS 9.4, maintenance 3, we added additional styling related to node-link diagrams. To complete your set of fonts, you can use the list below. You can use the CLASS statement as Chris said; but, if you have any node-link diagram output that uses ODS styles, it would use an inherited font instead of one that matched the others in your list.

 

class GraphFonts /
	'GraphDataFont'=("Tahoma",10pt) 
	'GraphUnicodeFont'=("Tahoma",10pt) 
	'GraphValueFont'=("Tahoma",10pt) 
	'GraphLabelFont'=("Tahoma",10pt) 
	'GraphLabel2Font'=("Tahoma",10pt) 
	'GraphFootnoteFont'=("Tahoma",8pt) 
	'GraphTitleFont'=("Tahoma",14pt) 
	'GraphTitle1Font'=("Tahoma",14pt) 
	'GraphAnnoFont'=("Tahoma",10pt)
    'NodeTitleFont' = ("Tahoma", 9pt)
    'NodeLabelFont' = ("Tahoma", 9pt)
    'NodeInputLabelFont' = ("Tahoma", 9pt)
    'NodeLinkLabelFont' = ("Tahoma", 9pt)
    'NodeDetailFont' = ("Tahoma", 7pt)
;

 

 

Version history
Last update:
‎11-01-2016 08:52 AM
Updated by:

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

Free course: Data Literacy Essentials

Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning  and boost your career prospects.

Get Started

Article Labels
Article Tags