Hi,
I am working on a bar graph in sgplot. The x-axis values currently are by Q1-2017, Q2-2017, Q3-2017, Q4-2017, Q1-2018, Q2-2018, Q3-2018, Q4-2018. I am hoping to keep the values for Q1, Q2, Q3, Q4 and add a bracket with 2017 and 2018 below the quarter labels. Is it possible to add brackets below the x axis? Attached is the current & expected display of the x axis values.
I would use Proc SGPANEL, you will not have the brackets, but it is visually close. See example below:
data have;
do year = 2017 to 2018;
do qtr = 1 to 4;
someDate = mdy(3*qtr, 1, year);
someValue = rand("integer", 100, 500);
qtrc = cats("Q", qtr(someDate));
output;
end;
end;
format
someDate date9.
someValue comma14.
;
run;
proc sgpanel data=have;
where someDate > "01apr2017"d;
panelby someDate / layout=columnlattice colheaderpos=bottom novarname uniscale=row proportional noborder;
vbar qtrc / response=someValue;
colaxis display=(nolabel);
format somedate year.;
run;
I would use Proc SGPANEL, you will not have the brackets, but it is visually close. See example below:
data have;
do year = 2017 to 2018;
do qtr = 1 to 4;
someDate = mdy(3*qtr, 1, year);
someValue = rand("integer", 100, 500);
qtrc = cats("Q", qtr(someDate));
output;
end;
end;
format
someDate date9.
someValue comma14.
;
run;
proc sgpanel data=have;
where someDate > "01apr2017"d;
panelby someDate / layout=columnlattice colheaderpos=bottom novarname uniscale=row proportional noborder;
vbar qtrc / response=someValue;
colaxis display=(nolabel);
format somedate year.;
run;
Thank you, this extremely helpful. I am able to plot the graph with panels for each year from 2017-2022 by quarter, also adding a grouping variable.
I have one follow-up question:
The code currently creates these graphs by quarter. I need to plot the data by month, but display Q1, Q2, Q3, Q4 with the panels for each year. Is that possible to do?
Here's what I have so far:
proc format;
picture fmt
low-high='9'(prefix='Q')
;
run;
data have;
call streaminit(123);
do year=2017 to 2019;
do month=1 to 12;
qtr=ceil(month/3);
value=rand('integer',1,100);
output;
end;
end;
format qtr fmt2.;
run;
proc sgpanel data=have ;
panelby year/layout=columnlattice onepanel spacing=0 noborder
colheaderpos=bottom novarname;
block x=month block=qtr/FILLTYPE=ALTERNATE nooutline transparency=0.3;
vbarparm category=month response=value;
colaxis label=' ';
rowaxis label=' ' ;
run;
Thank you so much, this worked well! I had 2 follow-up questions:
Here's my code & output:
proc sgpanel data=have ;
panelby year/layout=columnlattice onepanel spacing=0 noborder
colheaderpos=bottom novarname;
block x=month block=qtr/nooutline nofill;
vbarparm category=month response=value/group=arm groupdisplay=cluster;
colaxis label=' ' valuesrotate=diagonal;
rowaxis label=' ' min=0 max=50;
run;
Output:
1.My data only has values till 1/2022, why does the graph display all months for 2022?
You need add these two options.
proc format; picture fmt low-high='9'(prefix='Q') ; run; data have; call streaminit(123); do year=2017 to 2019; do month=1 to 12; qtr=ceil(month/3); value=rand('integer',1,100); output; end; end; format qtr fmt2.; run; data have; set have; if year=2019 and month in (5:12) then delete; run; proc sgpanel data=have ; panelby year/layout=columnlattice onepanel spacing=0 noborder colheaderpos=bottom novarname uniscale=row PROPORTIONAL ; block x=month block=qtr/FILLTYPE=ALTERNATE nooutline transparency=0.3; vbarparm category=month response=value; colaxis label=' '; rowaxis label=' ' ; run;
2.I want to remove the block values,
I didn't get any problems. I think that is because you used NOFILL option, remove it.
proc format; picture fmt low-high='9'(prefix='Q') ; run; data have; call streaminit(123); do year=2017 to 2019; do month=1 to 12; qtr=ceil(month/3); value=rand('integer',1,100); output; end; end; format qtr fmt2.; run; data have; set have; if year=2019 and month in (5:12) then delete; run; proc sgpanel data=have ; panelby year/layout=columnlattice onepanel spacing=0 noborder colheaderpos=bottom novarname uniscale=row PROPORTIONAL ; block x=month block=qtr/FILLTYPE=ALTERNATE nooutline nolabel novalues ; vbarparm category=month response=value; colaxis label=' '; rowaxis label=' ' ; run;
Thank you. When I add the uniscale and proportional options, it works fine till I add 'values' and 'valuesdisplay' options. The graph reverts back to showing data for all months for 2022.
I assume the values and valuesdisplay disable the uniscale and proportional options.
Please show a mockup of what your graph should look like.
NEED HELP - With values & values displayoptions
LOOKS GOOD -Without values & valuesdisplay options/*SAS Code below*/
proc format;
picture fmt low-high='9'(prefix="Q");
run;
data have;
call streaminit(123);
do year = 2017 to 2020;
do month= 1 to 12;
qtr= ceil(month/3);
value=rand('integer', 1, 100);
output;
end;
end;
format qtr fmt2.;
run;
data have;
set have;
if year=2017 and month eq 1 then delete;
if year=2020 and month in (2:12) then delete;
run;
**Graph w/o values & valuesdisplay options - looks as expected**;
**Graph w values & valuesdisplay options - NEED HELP - includes all quarters**;
ods graphics/reset attrpriority=none width=13in height=8in ;
proc sgpanel data = have;
panelby year/layout=columnlattice onepanel spacing=0 noborder
colheaderpos=bottom novarname uniscale=row proportional;
block x=month block=qtr/nooutline novalues filltype=alternate fillattrs=(color=white) altfillattrs=(color=white);
vbarparm category=month response=value ;
colaxis label= ' ' valuesrotate=diagonal ;
/*values=( 2 3 4 5 6 7 8 9 10 11 12 /*2017*/*/
/* 1 2 3 4 5 6 7 8 9 10 11 12 /*2018*/*/
/* 1 2 3 4 5 6 7 8 9 10 11 12 /*2019*/*/
/* 1 /*2020*/*/
/*valuesdisplay= ("Q1" "" "" "Q2" "" "" "Q3" "" "" "Q4" "" "" /*2017*/*/
/* "Q1" "" "" "Q2" "" "" "Q3" "" "" "Q4" "" "" /*2018*/*/
/* "Q1" "" "" "Q2" "" "" "Q3" "" "" "Q4" "" "" /*2019*/*/
/* "Q1"/*2020*/*/
;
rowaxis label= ' ';
run;
NEED HELP - graph with values and valuesdisplay option
LOOKS GOOD - graph without values and valuesdisplayoption
Have a go at this example, it uses two TEXT statements to "draw" the tickmarks as well as the Qn value. The BLOCK is optional.
data have;
call streaminit(123);
do year=2017 to 2019;
do month=1 to 12;
somedate = mdy(month,1,year);
tick = "'";
pos_tick = 0;
value=rand('integer',1,100);
length qtr_c $ 2;
qtr_c = cats("Q", ceil(month/3));
if month in (1,4,7,10) then do;
month2q = qtr_c;
pos_month2q = -1;
end;
else do;
call missing(month2q);
end;
output;
end;
end;
format somedate date9.;
run;
proc sgpanel data=have noautolegend ;
where somedate between "01jan2017"d and "01apr2019"d;
panelby year /
layout=columnlattice onepanel
spacing=5 noborder
colheaderpos=bottom novarname
uniscale=row proportional
;
* block x=month block=qtr_c / filltype=alternate nolabel novalues nooutline;
vbarbasic month / response=value ;
text x=month y=pos_tick text=tick /
textattrs=(color=blue ) position=bottom vcenter=bbox
;
text x=month y=pos_month2q text=month2q /
textattrs=(color=red ) position=bottom vcenter=bbox
;
colaxis display=none ;
rowaxis label=' '
offsetmin=0.04
;
run;
/*
It is hard to give you some advice without seeing your code
*/
proc format;
value fmt_month /*<----------*/
1='Jan'
2='Feb'
3='March'
4='April'
5='May'
;
picture fmt
low-high='9'(prefix='Q')
;
run;
data have;
call streaminit(123);
do year=2017 to 2019;
do month=1 to 12;
qtr=ceil(month/3);
value=rand('integer',1,100);
output;
end;
end;
format qtr fmt2.;
run;
data have;
set have;
if year=2019 and month in (5:12) then delete;
run;
proc sgpanel data=have ;
format month fmt_month.; /*<----------*/
panelby year/layout=columnlattice onepanel spacing=0 noborder
colheaderpos=bottom novarname uniscale=row PROPORTIONAL ;
block x=month block=qtr/FILLTYPE=ALTERNATE nooutline transparency=0.3;
vbarparm category=month response=value;
colaxis label=' ';
rowaxis label=' ' ;
run;
/*
Try PROC SGPANEL
*/
proc format;
picture fmt
low-high='9'(prefix='Q')
;
run;
data have;
call streaminit(123);
do year=2017 to 2019;
do qtr=1 to 4;
value=rand('integer',1,100);
output;
end;
end;
format qtr fmt2.;
run;
proc sgpanel data=have ;
panelby year/layout=columnlattice onepanel spacing=0 noborder
colheaderpos=bottom headerbackcolor=white novarname;
vbar qtr/response=value;
colaxis label=' ';
rowaxis label=' ';
run;
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.