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...
Related
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 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;
is there a way to detect an outlier from proc means while calculating min max Q1 and Q3?
the box plot procedure is not working on my SAS and I am trying to perform a boxplt in excel with the values from SAS.
Assuming you have a specific definition for what an outlier is, PROC UNIVARIATE can calculate the value that appears at that percentile using the PCTLPTS keyword on the OUTPUT statement. It also will identify extreme observations individually, so you can see the top few observations (if you have few enough observations that the number of extremes is likely to be <= 5).
The paper A SAS Application to Identify and Evaluate Outliers goes over a few of the ways you can look at outliers, including box plots and PROC UNIVARIATE, and includes some regression-based approaches as well.
If you want a 'standard boxplot' use the outbox= option in SAS to create the standard data set used for a box plot.
proc boxplot data=sashelp.class;
plot age*sex / outbox = xyz;
run;
I have a single continuous variable with highly skewed distribution. I have log transformed it for normalization. while creating a histogram of the variable with PROC UNIVARIATE (SAS 9.3), is there a way by which I can plot the transformed variable, but keep the values of original variable on x axis ?
if this topic has been already discussed then, I would really appreciate if someone can provide a link. Thank You.
You could use the SAS Graph Template Language (GTL) to do this. The documentation contains plenty of examples that you should be able to change and modify to your needs. The output from PROC UNIVARIATE is produced by the GTL so you should be able to generate something similar.
Take the output dataset from proc univariate and base the plot off that. You will need to reverse the transformations first.
Documentation for the GTL:
http://support.sas.com/documentation/cdl/en/grstatgraph/65377/HTML/default/viewer.htm#p1sxw5gidyzrygn1ibkzfmc5c93m.htm
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.