Add Title To SAS Output Graphs - templates

I'm using template and sgrender in SAS to create heatmaps based on a different class variable. I'd like the output to update the title based off of the class variable each time to what the value of the class variable. So far, my code is like this (it prints a string title if I tell it to, but i can't get it to vary depending on the variable):
proc template;
define statgraph heatmapparm;
begingraph;
entrytitle 'INSERT TITLE HERE'; *Update title here based on classVar;
layout overlay;
heatmapparm x=magX2 y=magZ2 colorresponse=percent / colormodel=(blue yellow red)
name="heatmapparm" xbinaxis=false ybinaxis=false datatransparency=0;
continuouslegend "heatmapparm" / location=outside valign=bottom;
endlayout;
endgraph;
end;
run;
title #byval(classVar);
proc sgrender data=dataSet template=heatmapparm;
by classVar;
run;
Thank you all!

Use Macro variables to alter the titles. Here is an example
%let classVar=VARIABLEVALUE1;
title &classVar.;
proc sgrender data=dataSet template=heatmapparm;
by &classVar.;
run;
You can always write cleaner code by putting the proc sgrender code inside a SAS MACRO.

Related

PROC REPORT WITH MACRO

I would like to create MACRO to produce a report (proc report) for each of datasets. For each report include title, "CYBOCS Compulsion Scale:Q6_#". Bold the line that has cycle 12 in it as cycle 12 is the primary endpoint. And using ODS RTF to output all reports to the personal drive
Here is the table look like:
Here is my code, I don't sure how to add bold line and how should I use ODS RTF to export reports
ODS RTF
%MACRO diff(var=);
PROC REPORT DATA=table_&var.;
TITLE "CYBOCS COMPULSION SCALE: &var";
RUN;
%MEND diff;
options mprint mlogic;
%diff(var=q6_1a);
%diff(var=q6_1b);
%diff(var=q6_2);
%diff(var=q6_3);
%diff(var=q6_4);
%diff(var=q6_5);
%diff(var=q6_6);
%diff(var=q6_7);
%diff(var=q6_date);
Use a compute block and add your condition. You can use call define() to conditionally change a style based on your logic. For example, if we wanted to bold the row for every BMW in sashelp.cars:
proc report data=sashelp.cars;
compute Make;
if(Make = 'BMW') then call define(_ROW_, 'style', 'style=[font_weight=bold]');
endcomp;
run;

SAS: How to get a Pie Chart to display the MEAN of a specific column?

I have created a simple pie chart, but I want the pie chart to display the MEAN (average) of a specific column, which is the "PRICE" attribute from my dataset. My dataset has two attributes - PRODUCT and PRICE.
Below, shows my SAS code used to create the pie chart - but I need some help on how to get the pie chart to display the MEAN for my "PRICE" attribute.
Thanks - any help is much appreciated.
PROC TEMPLATE;
DEFINE STATGRAPH MyPieChart;
BEGINGRAPH;
ENTRYTITLE 'AVERAGE PRICE OF PRODUCTS';
LAYOUT REGION;
PIECHART CATEGORY=PRODUCTS RESPONSE=PRICE; // I THINK THE CODE NEEDS CHANGING HERE?
ENDLAYOUT;
ENDGRAPH;
END;
RUN;
PROC SGRENDER TEMPLATE=MyPieChart DATA=WORK.IMPORT;
RUN;
Add option / STAT=MEAN.
Lots more info in the Graphics Template Language (GTL) PIECHART statement options documentation.
Example:
data have; input
products $ price; datalines;
A 1
A 2
A 3
B 11
B 12
B 13
C 5
C 7
C 8
C 10
;
ods html file = 'pie.html';
PROC TEMPLATE;
DEFINE STATGRAPH MyPieChart;
BEGINGRAPH;
ENTRYTITLE 'AVERAGE PRICE OF PRODUCTS';
LAYOUT REGION;
PIECHART
CATEGORY=PRODUCTS
RESPONSE=PRICE
/
STAT=MEAN
;
ENDLAYOUT;
ENDGRAPH;
END;
RUN;
PROC SGRENDER TEMPLATE=MyPieChart DATA=WORK.HAVE;
RUN;
ods html close;

SAS using macro in a title

What is the purpose of title Title "&TitleX" here?
Is there any difference between doing the first and second way?
%let TitleX=PROC PRINT Of Only &Cyl_Count Cylinder Vehicles; %let Cyl_Count=5;
Title "&TitleX";
proc print data=sashelp.cars;
where Cylinders=&Cyl_Count;
var Type Make Model Cylinders MSRP; run;
title PROC PRINT Of Only &Cyl_Count Cylinder Vehicles; %let Cyl_Count=5;
proc print data=sashelp.cars;
where Cylinders=&Cyl_Count;
var Type Make Model Cylinders MSRP; run;
There are two differences. One is that the macro variable exists and can be used for something else if you want. The second is how the TITLE statement is generated. The version that is using the TITLEX macro variables is using quotes and the other is not, but that really doesn't have anything to do with the macro variable.

SAS Proc Report changing header style attributes for an across variable

A sample SAS Proc report code is below. I want to change the color of the header background and foreground for one value of the across variable. I used a compute block to change the column background to light gray using the absolute column references c4 and c5. How do I change the header style attributes for c4 and c5 to background=gainboro and foreground=black?
data test;
length name $ 10 disease $ 10.;
infile datalines dsd;
input name $ disease cases rate;
datalines;
State,Fever,4847,25.16
State,Cold,25632,131.5
State,Flu,103825,535.82
Lincoln,Fever,3920,44.17
Lincoln,Cold,16913,190.18
Lincoln,Flu,62965,735.39
Washington,Fever,827,56.56
Washington,Cold,3609,234.26
Washington,Flu,16610,1078.8
Kings,Fever,1026,37.45
Kings,Cold,4984,181.85
Kings,Flu,18388,694.33
Sussex,Fever,1411,78.38
Sussex,Cold,5515,300.46
Sussex,Flu,13881,813.11
Queens,Fever,616,26.03
Queens,Cold,2496,107.75
Queens,Flu,12518,558.09
;
run;
proc report data=test nowd headline headskip
STYLE(Header)={background=charcoal foreground=white }
style(column)={background=gray foreground=black}
style(report)=[rules=rows bordercolor=white];
columns (name disease,(cases rate));
define name/group order=data 'County' style(column)={background=lighttgray} style(header)=[bordertopcolor=gainsboro background=gainsboro foreground=black];
define disease/across '' order=data ;
define cases/'Cases' format=comma9. ;
define rate/'Rate' format=comma12.1 ;
compute cases;
call define('_c4_','style','style={background=lighttgray}');
call define('_c5_','style','style={background=lighttgray}');
endcomp;
run;
quit;
run;
You can use formats to do something close to what you're asking, but I'm not sure it's possible to do what you're asking - maybe Cynthia Zender on communities.sas.com might?
data test;
length name $ 10 disease $ 10.;
infile datalines dsd;
input name $ disease cases rate;
datalines;
State,Fever,4847,25.16
State,Cold,25632,131.5
State,Flu,103825,535.82
Lincoln,Fever,3920,44.17
Lincoln,Cold,16913,190.18
Lincoln,Flu,62965,735.39
Washington,Fever,827,56.56
Washington,Cold,3609,234.26
Washington,Flu,16610,1078.8
Kings,Fever,1026,37.45
Kings,Cold,4984,181.85
Kings,Flu,18388,694.33
Sussex,Fever,1411,78.38
Sussex,Cold,5515,300.46
Sussex,Flu,13881,813.11
Queens,Fever,616,26.03
Queens,Cold,2496,107.75
Queens,Flu,12518,558.09
;
run;
proc format;
value $headerbackf
'Cold' = 'gainsboro'
other = 'charcoal';
value $headerforef
'Cold' = 'black'
other = 'white'
;
quit;
proc report data=test nowd headline headskip
STYLE(Header)={background=charcoal foreground=white }
style(column)={background=gray foreground=black}
style(report)=[rules=rows bordercolor=white];
columns (name disease,(cases rate));
define name/group order=data 'County' style(column)={background=lightgray} style(header)=[bordertopcolor=gainsboro background=gainsboro foreground=black];
define disease/across '' order=data style(header)={background=$HEADERBACKF. foreground=$HEADERFOREF.};
define cases/'Cases' format=comma9. style(header)=inherit;
define rate/'Rate' format=comma12.1 ;
compute cases;
call define('_c4_','style','style={background=lighttgray}');
call define('_c5_','style','style={background=lighttgray}');
endcomp;
run;
That gets that top row formatted, but, doesn't actually get the row you're asking for. I'm not sure it's possible to.
It's possible as #ChrisJ noted that you might be able to do this with CSS styles and nth child selection. It's also possible you can't, unfortunately, due to how SAS does things with PROC REPORT - in particular, in PROC REPORT everything gets shoved inside <tr>s including the header rows, so nth-child and sibling selectors are impossible due to the headers not being children or siblings of each other.
Here's an example of a kludgey version of this, using sashelp.cars as an example.
CSS: (save in a .css file on your drive somewhere, say "c:\temp\test.css"):
#import 'base.css';
/* Red the second (really third) column header value */
.table thead tr:nth-child(2) th:nth-child(3) {
color:red
}
/* Yellow background for the mpg headers under Europe */
.table thead tr:nth-child(3) th:nth-child(4),
.table thead tr:nth-child(3) th:nth-child(5)
{
background-color:yellow
}
/* Green the mpg-city values */
.table thead tr:nth-child(3) th:nth-child(even) {
color:green
}
SAS program: (assumes the above-saved CSS file)
ods html file='example.html' cssstyle='c:\temp\test.css'(html);
ods pdf file='example.pdf' cssstyle='c:\temp\test.css'(print);
proc sort data=sashelp.cars out=cars; by origin;
run;
proc report data=cars nowd;
columns type origin,(mpg_city mpg_highway);
define origin/across;
define type/group;
define mpg_City / analysis mean;
define mpg_highway / analysis mean;
run;
ods _all_ close;
This is partially based on Kevin Smith's Unveiling the power of Cascading Style Sheets (CSS) in ODS.
Unfortunately, we can't in any way identify a cell that has "MPG(City)" in it except by knowing they'll be even column numbers. We similarly can't identify a cell under a "Europe" except by knowing what cells those will be.
Try adding a dummy column _c to the end of your columns statement, and add a define & compute to go with it.
Also, ensure your colour names are actually valid, e.g. lighttgray is invalid and will not work.
columns ... _c ;
define _c / computed noprint ;
compute _c ;
call define('_c4_','style','style={background=lightgray}');
call define('_c5_','style','style={background=lightgray}');
endcomp ;

Use custom class instead of GraphValueText for textattrs option in PROC TEMPLATE?

Using SAS 9.3 and trying to adhere to DRY by defining a custom style and using it with multiple ENTRY statements throughout a PROC TEMPLATE's statgraph block.
Custom style:
proc template;
define style llama;
parent=styles.fancyPrinter;
style CustomFonts from GraphFonts /
'GraphValueFont'=("<sans-serif>, <MTsans-serif>",25pt,italic)
;
class foo from GraphValueText /
font = CustomFonts('GraphValueFont')
color = GraphColors('gtext');
end;
run;
and then opened by a style= option in an ODS statement. I try to use foo:
Entry halign=left "bar / 1000" / textattrs=foo;
but get the log message:
NOTE: The style element 'foo' in the option TEXTATTRS is invalid. The default will be used.
It works fine when the TEXTATTRS is set using a definition like this (but since I'm using it a bunch of times, it won't be DRY):
textattrs=GraphValueText(weight=bold size=16pt color=CX800080)
Also, I know ODS is reading the style definition, because if I do:
style GraphFonts from GraphFonts
and change the fonts, it'll impact the graphs.
I don't have a good answer unfortunately for how to do this, though it's possible one exists.
What I do think is that GTL isn't completely listening to you. For example:
proc template;
define style llama;
parent=styles.fancyPrinter;
style CustomFonts from GraphFonts /
'GraphValueFont'=("<sans-serif>, <MTsans-serif>",25pt,italic)
;
style graphUnicodeText from GraphValueText /
color=red;
style graphValueText from GraphValueText/
color=green;
end;
run;
proc template;
define statgraph entry;
begingraph;
layout overlay;
entry halign=right "First entry statement" /
valign=top textattrs=graphValueText;
histogram weight;
entry halign=right "Second entry statement" /
textattrs=graphUnicodeText;
entry halign=right "Third entry statement" /
valign=bottom pad=(bottom=40px);
endlayout;
endgraph;
end;
run;
ods _all_ close;
ods html file="c:\temp\test.html" path="" gpath="c:\temp\" style=llama;
proc sgrender data=sashelp.class template=entry;
run;
ods html close;
Notice you don't get any errors about GraphUnicodeText... but you also don't get any effect from it. My guess is that GTL is doing its work with only partial awareness of the style, and thus isn't able to always respect what you ask it to do.
My suggestion (at least until/unless Sanjay or Dan or similar can help you find a better one) is to use a macro variable and/or a dynamic variable for this purpose.
proc template;
define style llama;
parent=styles.fancyPrinter;
style CustomFonts from GraphFonts /
'GraphValueFont'=("<sans-serif>, <MTsans-serif>",25pt,italic)
;
style graphUnicodeText from GraphValueText /
color=red;
style graphValueText from GraphValueText/
color=green;
end;
run;
proc template;
define statgraph entry;
begingraph;
layout overlay;
dynamic entrycolor;
entry halign=right "First entry statement" /
valign=top;
histogram weight;
entry halign=right "Second entry statement" /
textattrs=(color=entrycolor);
entry halign=right "Third entry statement" /
valign=bottom pad=(bottom=40px);
endlayout;
endgraph;
end;
run;
ods _all_ close;
ods html file="c:\temp\test.html" path="" gpath="c:\temp\" style=llama;
proc sgrender data=sashelp.class template=entry;
dynamic entrycolor="red";
run;
ods html close;
You can then reuse entrycolor in multiple places in the template, and allow it to be specified by the user at runtime. It's not ideal, but it does work, at least...