Hi
I'm trying to emulate something like:
proc gchart data=sashelp.baseball;
hbar team / asc sumvar=natbat;
run;
in a proc template. I can get the vertical bars to come out but not in ascending sequence by the sum of the response variable. How can I get it to come out in order?
Current code:
proc template;
define statgraph bb;
begingraph;
layout overlay /;
barchart response=natbat category=team;
endlayout;
endgraph;
end;
run;
proc sgrender data=sashelp.baseball template=bb;
run;
Thanks!
--Ben
If that gets you started then you might add the TMPLOUT="filename" option to the proc statement. That will create a text file with the template code to generate the given graph.
It goes help to provide a more complete example of where you are going with this as it may avoid pitfalls like attempting to use a Layout Gridded where you want Layout Datalattice or ...
Something like this? Version of SAS you are using can make this problematic as I think the categoryorder is a relatively recent option.
proc sgplot data=sashelp.baseball; vbar team/response=natbat stat=sum categoryorder=respasc; run;
Sorry, using 9.4 M4.
I'm sure that would work. Unfortunately the actual code is part of a larger proc template begingraph block that I can't separate out. Otherwise I would have used something simpler, like the gchart approach.
?
--Ben
If that gets you started then you might add the TMPLOUT="filename" option to the proc statement. That will create a text file with the template code to generate the given graph.
It goes help to provide a more complete example of where you are going with this as it may avoid pitfalls like attempting to use a Layout Gridded where you want Layout Datalattice or ...
Of course. I always forget that as an option.
The part I couldn't find was
yaxisopts=(discreteOpts=(sortOrder=Data))
that got me what I needed.
Thanks so much!
--Ben
Tried the tmplout= option and it generated the following code:
proc template;
define statgraph sgplot;
dynamic _NEGATIVE_;
dynamic _ticklist_;
begingraph / collation=binary;
layout overlay / yaxisopts=(discreteOpts=(sortOrder=Data))
yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split)
yaxisopts=(type=Discrete reverse=true discreteOpts=(tickValueList=_ticklist_ tickValueListPolicy=Union))
y2axisopts=(type=Discrete reverse=true discreteOpts=(tickValueList=_ticklist_ tickValueListPolicy=Union));
BarChartParm X=Team Y=_Sum1_nAtBat_ / primary=true orient=horizontal LegendLabel="Times at Bat in 1986" NAME="HBAR";
endlayout;
endgraph;
end;
run;
I ran that with an sgrender per:
proc sgrender data=sashelp.baseball template=sgplot; run;
That didn't go anywhere due to the 2 dynamic variables. I commented out the _ticklist_ dynamic variable and the reference to it but I'm not sure how to handle the _NEGATIVE_ reference. Also, is the _Sum1_nAtBat_ a variable from a temporary file that is created?
Tried a few more variants with no success. ?
--Ben
Note that the template uses Barchartparm. That element requires presummarized data. So the SGPLOT internally summarizes the data.
So you need to summarize the data as well as remove the offending dynamic variables.
proc template; define statgraph baseballplot; /* dynamic _NEGATIVE_;*/ /* dynamic _ticklist_;*/ begingraph / collation=binary; layout overlay / yaxisopts=(discreteOpts=(sortOrder=Data)) yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split) yaxisopts=(type=Discrete reverse=true /*discreteOpts=(tickValueList=_ticklist_ tickValueListPolicy=Union)*/) y2axisopts=(type=Discrete reverse=true /* discreteOpts=(tickValueList=_ticklist_ tickValueListPolicy=Union)*/); BarChartParm X=Team Y=_Sum1_nAtBat_ / primary=true orient=horizontal LegendLabel="Times at Bat in 1986" NAME="HBAR"; endlayout; endgraph; end; run; proc summary data=sashelp.baseball nway; class team; var natbat; output out= basesum sum=_sum1_natbat_; run; Proc sort data=basesum; by _sum1_natbat_; run; proc sgrender data=basesum template=baseballplot; ; run;
If you don't like the ugly _sum1_natbat_ variable name then change it in the tempplate and the proc summary code.
Better would likely be to replace Team, _sum1_natbat_ and legendlable text with dynamic variables to use the template more flexibly
The production code will be a lot cleaner. 🙂
Substituting the following, building on the output from the generated template:
proc summary data=sashelp.baseball nway;
class team;
var natbat;
output out=sumbb sum=;
run;
proc sort data=sumbb;
by descending natbat;
run;
proc template;
define statgraph sgplot;
begingraph / collation=binary;
layout overlay / yaxisopts=(discreteOpts=(sortOrder=Data))
yaxisopts=(labelFitPolicy=Split) y2axisopts=(labelFitPolicy=Split) ;
BarChartParm X=Team Y=nAtBat / primary=true orient=horizontal LegendLabel="Times at Bat in 1986" NAME="HBAR";
endlayout;
endgraph;
end;
run;
proc sgrender data=sumbb template=sgplot;
run;
Is what worked. It sorts the response values in ascending order in the graph. I'm just not sure why....as I had to use descending in the proc sort to make it work. ?
--Ben
Is what worked. It sorts the response values in ascending order in the graph. I'm just not sure why....as I had to use descending in the proc sort to make it work. ?
--Ben
Probably just the way you think of HBAR order and the procedure coding isn't quite intuitive for you. If you want the longest bar at the top that is the largest value=descending sort order (top to bottom), if you want the longest bar at the bottom that is the largest value =ascending sort order
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.