How to change SAS sgplot refline label orientation - sas

I am plotting in SAS using SGPLOT. I added a few reflines on the x-axis to mark certain dates however, the labels of these reflines become vertical as shown here. With only three reflines, the labels were horizontal as I hoped. However, as I added more reflines, the labels turned vertical.
Is there a way to change the orientation of the label? Or is it just because there is not enough space...
Here is my code for the refline:
refline '01Jul2002'd / axis=x label = "[1]"
labelloc=outside labelpos=max labelattrs=(size=6.5pt family="arial")

SAS is automatically rotating them in an attempt to "fit" them (or to indicate they're overlapping visually), more than likely. Using Reeza's example, this is trivial to reproduce.
proc sgplot data=sashelp.stocks(where=(stock='IBM'));
series x=date y=open;
refline '01Jul2002'd / axis=x label = "[1]"
labelloc=outside labelpos=max labelattrs=(size=6.5pt family="arial");
refline '02Jul2002'd / axis=x label = "[2]"
labelloc=outside labelpos=max labelattrs=(size=6.5pt family="arial");
run;
With just one, it is horizontal, but the second one causes a rotation.
I don't see a way to fix this other than having fewer reference lines so that the labels don't try to overlap. Neither SGPLOT nor GTL seems to give an option (usually named FITPOLICY) for reference line plots. You could use a different kind of plot I suppose which might give you more options, or use annotation rather than reference lines (it's possible to duplicate reference lines entirely using Annotation, the refline plot itself is just a convenience to avoid having to use the Annotate facility).
You may want to consider asking this question on http://communities.sas.com and seeing if one of the developers (Sanjay, Dan H, etc.) has a workaround or can suggest something specific other than annotation. If you do I suggest you include an example like the above so the question is clear.

I cannot replicate your issue. Here's code that doesn't replicate your issue. This means either you've set something else somewhere else that's causing this or you could be using a different version. I'm on SAS 9.4 TS1M3. In the future please include code so we can replicate your issue.
proc sgplot data=sashelp.stocks(where=(stock='IBM'));
series x=date y=open;
refline '01Jul2002'd / axis=x label = "[1]"
labelloc=outside labelpos=max labelattrs=(size=6.5pt family="arial");
run;

Related

SAS-sgplot-add label to bar clusters

I am looking for an option to add label to bar clusters.
I want the values: 0.940, 0.250, 0.520, 0.580, and 0.230 in the middle of the clustered bars, like the following:
Assuming you have SAS 9.4 TS1M2 or later, you have an option, seglabel, which specifically does this, other than the 'display only once', which I don't think is a thing you can get out of the box.
proc sgplot data=sashelp.cars;
vbar cylinders/group=origin groupdisplay=cluster seglabel;
run;
If you don't, or you need more control than that gives you (such as your request to display only once), there are options, such as in my paper, Labelling without the hassle; it is for stacked bar charts, but the general approach would work for clustered also, you'd just have to adjust things some.
This gets somewhat close, and probably would get nearly perfect for your case; it needs some customization for groups that don't have all three group values present, but you don't have that in your example.
More complex solutions exist using annotations or GTL, as well, with this general approach (of overlaying on the precomputed bars a label).
proc summary data=sashelp.cars;
class origin cylinders;
types origin*cylinders;
var mpg_city;
output out=cars_summary(drop=_:) n(mpg_city)=count;
run;
data cars_labels;
set cars_summary;
if origin='Asia' then count_asia=count;
if origin='USA' then count_usa=count;
if origin='Europe' then count_eu=count;
ypos = floor(count/2);
run;
proc sgplot data=cars_labels;
vbarparm category=cylinders response=count/group=origin groupdisplay=cluster;
scatter x=cylinders y=ypos/markerchar=count_asia discreteoffset=-0.35;
scatter x=cylinders y=ypos/markerchar=count_usa discreteoffset=0.20;
scatter x=cylinders y=ypos/markerchar=count_eu discreteoffset=-0.1;
run;

I don't see an explanatory legend in SAS proc freq

I have a problem with the legend not being visible at cross tabulation in porc freq in SAS. How can I show it?
I see only a table:
But I want to also see a legend:
PROC FREQ does not have a legend per se, but you can use the title statement to put some information there, or footer.
If you want better control, use PROC TABULATE which has substantial ability to customize the output, including the box option which places whatever information you want in the top-left corner of the table.
If you run the following:
proc template;
source Base.Freq.CrossTabFreqs;
run;
Then check your log, you should see:
define crosstabs Base.Freq.CrossTabFreqs;
notes "Crosstabulation table";
cellvalue Frequency Expected Deviation CellChiSquare TotalPercent Percent RowPercent ColPercent CumColPercent;
header TableOf ControllingFor;
footer NoObs Missing;
If you do not, that means that someone has modified your PROC FREQ base template and that's why it's not showing. In this case you would need to replace your default SAS installation templates by obtaining clean copies from a different source. It may also need to align with your SAS version.
If you have a colleague or different SAS installation that is operating as expected, you can run the PROC TEMPLATE above, then copy the code from the log and re-create the template as:
proc template;
<insert copied code from log>;
run;
And you probably realize, but this is why modifying templates is generally a last resort for customizing data/output and usually you should never modify the default templates.

In SAS, using ODS TAGSETS.ExcelXP and proc report, how can I adjust bordercolor for ONE column only?

I have an excel file I want to create from a PROC REPORT step, using ODS TAGSETS.ExcelXP and an adjusted version of the style MINIMAL. I want to have the first column in the output to have white borders (so it doesn't look like it has a border) while the rest of the columns have the black border from MINIMAL still.
I have been trying all day to do it but alas, no success! It is either changing all the borders, or none.
I have tried using
proc template to edit the minimal style
style=[bordercolor=white] and all variants to change borders (eg. borderleftcolor etc.)
style(column)=[bordercolor=white] where this and the one above were tried all over the place in proc report (as a proc report style, as a define style).
Please help! :(
An example output would be like below:
Example Output

Remove overlapping X-axis labels on a barchart

Short of using annotations, I have been unable to find a reasonable way to prevent my x-axis labels from overlapping when using a barchartparm in SAS. From the documentation, they clearly state that barcharts use a discrete axis and the other axis types such as time are not permissible for them. Although conceptually this makes sense it seems like an 'unnecessary' limitation to enforce as it leaves no control over the x-axis labeling as every discrete label will be printed.
Sample data:
data test;
format rpt_date date9.;
do rpt_date=date()-90 to date();
root = round(ranuni(1) *100,1);
output;
end;
run;
Define the chart template:
proc template;
define statgraph giddyup;
begingraph;
layout overlay;
barchartparm x=rpt_date y=root ;
endlayout;
endgraph;
end;
run;
Create the chart:
proc sgrender data=test template=giddyup;
run;
Result:
I tried to be duct-tape it and create a custom format for the x-axis that would 'blank-out' many of the values, and although the chart was produced, it stacked all the blanks together (??) and also produced a warning.
I've also tried using the alternate x2axisopts and setting the axis to secondary with no luck.
If I used a series chart I would be able to control the axis fine, but in my case the data is much easier to interpret as a barchart. Perhaps they needed to add additional options to the xaxisopts for barcharts.
The most frustrating thing here is that it's something that you can do in excel in 2 seconds, and to me seems like it would be a very common chart in excel, that is not easily reproducible in SAS!
EDIT: I also don't want to use proc gchart .
Ok now I feel silly. Turns out that histograms will achieve the same result nicely:
histogramparm x=rpt_date y=root ;
Still a valuable question I guess as I spent a lot of time googling for answers and could not find a solution.
Good thing I didn't want it horizontal...

Interleaving output from two different procedures with a by value

I have a large SAS dataset and I would like to make a series of tables and charts using by value processing. I am outputing these to a PDF.
Is there any way to get SAS to alternate between the table and the chart as it goes through the data? Right now, I have to print all of the tables first and then print the charts. If it were just 4 tables/charts, then I would be ok writing
Here is a simple example:
data sample;
input byval $ item $ amount;
datalines;
A X 15
A Y 16
A Z 12
B X 25
B Y 10
B Z 18
;
run;
symbol1 i=j;
proc print data=sample;
by byval;
var item amount;
run;
proc gplot uniform data=sample;
by byval;
plot amount*item;
run;
This prints 2 tables, followed by 2 charts.
I would like the Chart for "A" to come after the table for "A" so that the reader can flip through the pdf and always see the associated charts and tables together.
I could write separate procs for each one, but then the gplot won't have a uniform axis (and it gets messy if I have 100 different groups instead of 2).
I thought about pumping them into greplay but then you can't use titles with "#BYVAL1".
Is there any easy way to do this?
I've never used it, but it may be worth checking out ODS DOCUMENT. This allows you to store the output of all your procedures and then reference specific items from them using PROC DOCUMENT.
Below is a link to the SAS website with useful information about this, in particular the paper by Cynthia Zender for the SAS Global Forum 2009.
http://support.sas.com/rnd/base/ods/odsdocument/index.html
Cynthia also regularly contributes to the SAS Support Communities website (https://communities.sas.com/community/support-communities), so it may be worth asking on there if you are still stuck.
Good luck
I don't know of any way to do what you ask directly. GREPLAY is probably the closest you'll come; the primary problem is that SAS processes the PROCs linearly, first processing the entire PROC PRINT, then the entire PROC GPLOT. GREPLAY would allow you to redisplay the output, but if that doesn't work for your needs due to the #BYVAL issue, I'm not sure there's a better solution. Perhaps you can modify the title afterwards (not sure if GREPLAY allows this)?
You could try using ODS LAYOUT, but I don't think that would be any better. The one way it could be better is if you can work out having two columns on a 'page', one column being the PROC PRINT outputs, one the PROC GPLOT, and then print the columns one page than the other. I don't think this is possible, but it might be worth exploring.
You might also try setting up a macro to do each BYVAL separately, defining the axis in a uniform manner manually (ie, defining it based on your own calculation of the correct axis parameters, as an argument to the macro). That is probably the easiest solution that might still allow #BYVAL to work properly.
You might also try browsing about Richard DeVenezia's site (http://www.devenezia.com/downloads/sas/samples/ ) which has a lot of examples of SAS/GRAPH solutions. He also posts on SAS-L (sasl#listserv.uga.edu) sometimes, not sure if I've seen him on StackOverflow. He's probably the person most likely to be able to answer the question that I know of.