I am looking to generate a bargraph and line graphs with two axis using proc template. However I am having difficulty to get further. I really appreciate your help.
1. my barchart should starts from the x-axis, instead of line at Y=0
2. want my scatter and Series plot should start from (0,0). I tried to control but not successful
3. I want to duplicate the Score at each Month (Start from Month 1 to Month 12). and generate the same graph where we have two bars at each months. Example, at Month 1 I have score 3, I need score 3 and score 6 bars..
/* Create the monthly_score dataset */
data monthly_score;
length trtpn 8 visit $10 score 8 avg 8;
call streaminit(123);
do trtpn = 1 to 2;
do month = 1 to 12;
/* Create visit name */
visit = cats('Month', month);
score = floor(rand('uniform') * 6);
avg = .;
if month = 6 then do;
if trtpn = 1 then avg = 3.5;
else avg = 3.5 + (rand('uniform') - 0.5) * 0.4;
end;
else if month = 12 then do;
if trtpn = 1 then avg = 6.8;
else avg = 6.8 + (rand('uniform') - 0.5) * 0.4;
end;
if avg ne . then avg = round(avg, 0.1);
output;
end;
end;
drop month;
run;
/* Create dummy record for BL with avg=0 but score missing */
data dummy;
visit = "BL";
avg = 0;
trtpn = 1;
score = .;
run;
/* Create dataset with counts for trtpn=1 */
data monthly_score_trt1;
set monthly_score dummy;
where trtpn = 1;
run;
proc sort data = monthly_score_trt1;
by trtpn visit;
run;
/* Create a format to display month names */
proc format;
value visitfmt
0 = " "
1 = "Month1"
2 = "Month2"
3 = "Month3"
4 = "Month4"
5 = "Month5"
6 = "Month6"
7 = "Month7"
8 = "Month8"
9 = "Month9"
10 = "Month10"
11 = "Month11"
12 = "Month12";
run;
/* Create dataset with numeric visit variable */
data bar_data;
set monthly_score_trt1;
by trtpn visit;
if visit = "BL" then visit_num = 0;
else visit_num = input(scan(visit, -1, 'Month'), 8.);
bar_count = score;
if visit = "BL" then bar_count = .;
keep trtpn visit visit_num score avg bar_count;
run;
proc sort data=bar_data;
by visit_num;
run;
ods path(prepend) work.templat(update);
/* Create template with dual y-axes */
proc template;
define statgraph bargraph_trt1_dual;
begingraph;
entrytitle "Bar Graph by Visit for School Group 1";
entrytitle "with Counts Displayed on Top";
layout overlay /
xaxisopts=(
label="Visit"
type=linear
linearopts=(
viewmin=1 viewmax=12
tickvaluelist=(1 2 3 4 5 6 7 8 9 10 11 12)
tickvalueformat=visitfmt.
TICKVALUEFITPOLICY=rotate
TICKVALUEROTATION=DIAGONAL
TICKVALUEPRIORITY=true)
)
yaxisopts=(
label="Score Values"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=1)
)
)
y2axisopts=(
label="Average Score"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=.5)
)
);
barchart x=visit_num y=score /
fillattrs=(color=CX4A7DB4 transparency=0.2)
outlineattrs=(color=CX4A7DB4 thickness=1)
barwidth=0.6
name="bars"
legendlabel="Score Values"
includemissinggroup=false
yaxis=y
;
scatterplot x=visit_num y=score /
markerattrs=(symbol=square size=0)
datalabel=bar_count
datalabelposition=top
datalabelattrs=(
size=10pt
weight=bold
color=black
)
yaxis=y;
scatterplot x=visit_num y=avg /
markerattrs=(
symbol=circlefilled
size=8
color=CXFF7F0E
)
name="avg"
legendlabel="Average Score (Month 6 & 12)"
yaxis=y2;
seriesplot x=visit_num y=avg /
lineattrs=(
pattern=shortdash
color=CXFF7F0E
thickness=2
)
name="series"
legendlabel="Average Trend"
yaxis=y2;
/* Reference line to mark start of months */
*referenceline x=0.5 /
lineattrs=(pattern=solid color=lightgray thickness=1)
curvelabel="Baseline"
curvelabelposition=min;
/* Legend */
discretelegend "bars" "avg" "series" /
location=outside
halign=center
border=true
autoalign=(bottom);
endlayout;
endgraph;
end;
run;
/* Render the graph with dual axes */
proc sgrender data=bar_data template=bargraph_trt1_dual;
format score 4.1 avg 4.1 visit_num visitfmt.;
label score="Score Value"
avg="Average Score"
visit="Visit"
bar_count="Count";
run;
If you need to display these two bar with two different color:
/* Create the monthly_score dataset */
data monthly_score;
length trtpn 8 visit $10 score 8 avg 8;
call streaminit(123);
do trtpn = 1 to 2;
do month = 1 to 12;
/* Create visit name */
visit = cats('Month', month);
score = floor(rand('uniform') * 6);
avg = .;
if month = 6 then do;
if trtpn = 1 then avg = 3.5;
else avg = 3.5 + (rand('uniform') - 0.5) * 0.4;
end;
else if month = 12 then do;
if trtpn = 1 then avg = 6.8;
else avg = 6.8 + (rand('uniform') - 0.5) * 0.4;
end;
if avg ne . then avg = round(avg, 0.1);
output;
end;
end;
drop month;
run;
/* Create dummy record for BL with avg=0 but score missing */
data dummy;
visit = "BL";
avg = 0;
trtpn = 1;
score = .;
run;
/* Create dataset with counts for trtpn=1 */
data monthly_score_trt1;
set monthly_score dummy;
if trtpn=2 then call missing(avg);
run;
proc sort data = monthly_score_trt1;
by trtpn visit;
run;
/* Create a format to display month names */
proc format;
value visitfmt
0 = " "
1 = "Month1"
2 = "Month2"
3 = "Month3"
4 = "Month4"
5 = "Month5"
6 = "Month6"
7 = "Month7"
8 = "Month8"
9 = "Month9"
10 = "Month10"
11 = "Month11"
12 = "Month12";
run;
/* Create dataset with numeric visit variable */
data bar_data;
set monthly_score_trt1;
by trtpn visit;
if visit = "BL" then visit_num = 0;
else visit_num = input(scan(visit, -1, 'Month'), 8.);
bar_count = score;
if visit = "BL" then bar_count = .;
keep trtpn visit visit_num score avg bar_count;
run;
proc sort data=bar_data;
by trtpn visit_num;
run;
ods path(prepend) work.templat(update);
/* Create template with dual y-axes */
proc template;
define statgraph bargraph_trt1_dual;
begingraph;
entrytitle "Bar Graph by Visit for School Group 1";
entrytitle "with Counts Displayed on Top";
layout overlay /
xaxisopts=( OFFSETMIN=0
label="Visit"
type=linear
linearopts=(
viewmin=1 viewmax=12
tickvaluelist=(1 2 3 4 5 6 7 8 9 10 11 12)
tickvalueformat=visitfmt.
TICKVALUEFITPOLICY=rotate
TICKVALUEROTATION=DIAGONAL
TICKVALUEPRIORITY=true)
)
yaxisopts=( OFFSETMIN=0
label="Score Values"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=1)
)
)
y2axisopts=( OFFSETMIN=0
label="Average Score"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=.5)
)
);
barchart x=visit_num y=score /
/* fillattrs=(color=CX4A7DB4 transparency=0.2)*/
outlineattrs=(color=CX4A7DB4 thickness=1)
barwidth=0.6
name="bars"
legendlabel="Score Values"
includemissinggroup=false
yaxis=y
BARLABEL=on
GROUP=trtpn
GROUPDISPLAY=cluster
OUTLINEATTRS=(thickness=0)
;
/* scatterplot x=visit_num y=score /*/
/* markerattrs=(symbol=square size=0)*/
/* datalabel=bar_count*/
/* datalabelposition=top*/
/* datalabelattrs=(*/
/* size=10pt */
/* weight=bold */
/* color=black*/
/* )*/
/* yaxis=y;*/
scatterplot x=visit_num y=avg /
markerattrs=(
symbol=circlefilled
size=8
color=CXFF7F0E
)
name="avg"
legendlabel="Average Score (Month 6 & 12)"
yaxis=y2;
seriesplot x=visit_num y=avg /
lineattrs=(
pattern=shortdash
color=CXFF7F0E
thickness=2
)
name="series"
legendlabel="Average Trend"
yaxis=y2;
/* Reference line to mark start of months */
*referenceline x=0.5 /
lineattrs=(pattern=solid color=lightgray thickness=1)
curvelabel="Baseline"
curvelabelposition=min;
/* Legend */
discretelegend "bars" "avg" "series" /
location=outside
halign=center
border=true
autoalign=(bottom);
endlayout;
endgraph;
end;
run;
/* Render the graph with dual axes */
proc sgrender data=bar_data template=bargraph_trt1_dual;
format score 4.0 avg 4.1 visit_num visitfmt.;
label score="Score Value"
avg="Average Score"
visit="Visit"
bar_count="Count";
run;
You need to use option offsetmin=0 .
And the third question I don't understand , you want to display two bars one by one ?
layout overlay /
xaxisopts=( OFFSETMIN=0
label="Visit"
type=linear
linearopts=(
viewmin=1 viewmax=12
tickvaluelist=(1 2 3 4 5 6 7 8 9 10 11 12)
tickvalueformat=visitfmt.
TICKVALUEFITPOLICY=rotate
TICKVALUEROTATION=DIAGONAL
TICKVALUEPRIORITY=true)
)
yaxisopts=( OFFSETMIN=0
label="Score Values"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=1)
)
)
y2axisopts=( OFFSETMIN=0
label="Average Score"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=.5)
)
);
Here is an example:
/* Create the monthly_score dataset */
data monthly_score;
length trtpn 8 visit $10 score 8 avg 8;
call streaminit(123);
do trtpn = 1 to 2;
do month = 1 to 12;
/* Create visit name */
visit = cats('Month', month);
score = floor(rand('uniform') * 6);
avg = .;
if month = 6 then do;
if trtpn = 1 then avg = 3.5;
else avg = 3.5 + (rand('uniform') - 0.5) * 0.4;
end;
else if month = 12 then do;
if trtpn = 1 then avg = 6.8;
else avg = 6.8 + (rand('uniform') - 0.5) * 0.4;
end;
if avg ne . then avg = round(avg, 0.1);
output;
end;
end;
drop month;
run;
/* Create dummy record for BL with avg=0 but score missing */
data dummy;
visit = "BL";
avg = 0;
trtpn = 1;
score = .;
run;
/* Create dataset with counts for trtpn=1 */
data monthly_score_trt1;
set monthly_score dummy;
run;
proc sort data = monthly_score_trt1;
by trtpn visit;
run;
/* Create a format to display month names */
proc format;
value visitfmt
0 = " "
1 = "Month1"
2 = "Month2"
3 = "Month3"
4 = "Month4"
5 = "Month5"
6 = "Month6"
7 = "Month7"
8 = "Month8"
9 = "Month9"
10 = "Month10"
11 = "Month11"
12 = "Month12";
run;
/* Create dataset with numeric visit variable */
data bar_data;
set monthly_score_trt1;
by trtpn visit;
if visit = "BL" then visit_num = 0;
else visit_num = input(scan(visit, -1, 'Month'), 8.);
bar_count = score;
if visit = "BL" then bar_count = .;
keep trtpn visit visit_num score avg bar_count;
run;
proc sort data=bar_data;
by trtpn visit_num;
run;
ods path(prepend) work.templat(update);
/* Create template with dual y-axes */
proc template;
define statgraph bargraph_trt1_dual;
begingraph;
entrytitle "Bar Graph by Visit for School Group 1";
entrytitle "with Counts Displayed on Top";
layout overlay /
xaxisopts=( OFFSETMIN=0
label="Visit"
type=linear
linearopts=(
viewmin=1 viewmax=12
tickvaluelist=(1 2 3 4 5 6 7 8 9 10 11 12)
tickvalueformat=visitfmt.
TICKVALUEFITPOLICY=rotate
TICKVALUEROTATION=DIAGONAL
TICKVALUEPRIORITY=true)
)
yaxisopts=( OFFSETMIN=0
label="Score Values"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=1)
)
)
y2axisopts=( OFFSETMIN=0
label="Average Score"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=.5)
)
);
barchart x=visit_num y=score /
fillattrs=(color=CX4A7DB4 transparency=0.2)
outlineattrs=(color=CX4A7DB4 thickness=1)
barwidth=0.6
name="bars"
legendlabel="Score Values"
includemissinggroup=false
yaxis=y
BARLABEL=on
GROUP=trtpn
GROUPDISPLAY=cluster
;
/* scatterplot x=visit_num y=score /*/
/* markerattrs=(symbol=square size=0)*/
/* datalabel=bar_count*/
/* datalabelposition=top*/
/* datalabelattrs=(*/
/* size=10pt */
/* weight=bold */
/* color=black*/
/* )*/
/* yaxis=y;*/
scatterplot x=visit_num y=avg /
markerattrs=(
symbol=circlefilled
size=8
color=CXFF7F0E
)
name="avg"
legendlabel="Average Score (Month 6 & 12)"
yaxis=y2;
seriesplot x=visit_num y=avg /
lineattrs=(
pattern=shortdash
color=CXFF7F0E
thickness=2
)
name="series"
legendlabel="Average Trend"
yaxis=y2;
/* Reference line to mark start of months */
*referenceline x=0.5 /
lineattrs=(pattern=solid color=lightgray thickness=1)
curvelabel="Baseline"
curvelabelposition=min;
/* Legend */
discretelegend "bars" "avg" "series" /
location=outside
halign=center
border=true
autoalign=(bottom);
endlayout;
endgraph;
end;
run;
/* Render the graph with dual axes */
proc sgrender data=bar_data template=bargraph_trt1_dual;
format score 4.0 avg 4.1 visit_num visitfmt.;
label score="Score Value"
avg="Average Score"
visit="Visit"
bar_count="Count";
run;
If you need to display these two bar with two different color:
/* Create the monthly_score dataset */
data monthly_score;
length trtpn 8 visit $10 score 8 avg 8;
call streaminit(123);
do trtpn = 1 to 2;
do month = 1 to 12;
/* Create visit name */
visit = cats('Month', month);
score = floor(rand('uniform') * 6);
avg = .;
if month = 6 then do;
if trtpn = 1 then avg = 3.5;
else avg = 3.5 + (rand('uniform') - 0.5) * 0.4;
end;
else if month = 12 then do;
if trtpn = 1 then avg = 6.8;
else avg = 6.8 + (rand('uniform') - 0.5) * 0.4;
end;
if avg ne . then avg = round(avg, 0.1);
output;
end;
end;
drop month;
run;
/* Create dummy record for BL with avg=0 but score missing */
data dummy;
visit = "BL";
avg = 0;
trtpn = 1;
score = .;
run;
/* Create dataset with counts for trtpn=1 */
data monthly_score_trt1;
set monthly_score dummy;
if trtpn=2 then call missing(avg);
run;
proc sort data = monthly_score_trt1;
by trtpn visit;
run;
/* Create a format to display month names */
proc format;
value visitfmt
0 = " "
1 = "Month1"
2 = "Month2"
3 = "Month3"
4 = "Month4"
5 = "Month5"
6 = "Month6"
7 = "Month7"
8 = "Month8"
9 = "Month9"
10 = "Month10"
11 = "Month11"
12 = "Month12";
run;
/* Create dataset with numeric visit variable */
data bar_data;
set monthly_score_trt1;
by trtpn visit;
if visit = "BL" then visit_num = 0;
else visit_num = input(scan(visit, -1, 'Month'), 8.);
bar_count = score;
if visit = "BL" then bar_count = .;
keep trtpn visit visit_num score avg bar_count;
run;
proc sort data=bar_data;
by trtpn visit_num;
run;
ods path(prepend) work.templat(update);
/* Create template with dual y-axes */
proc template;
define statgraph bargraph_trt1_dual;
begingraph;
entrytitle "Bar Graph by Visit for School Group 1";
entrytitle "with Counts Displayed on Top";
layout overlay /
xaxisopts=( OFFSETMIN=0
label="Visit"
type=linear
linearopts=(
viewmin=1 viewmax=12
tickvaluelist=(1 2 3 4 5 6 7 8 9 10 11 12)
tickvalueformat=visitfmt.
TICKVALUEFITPOLICY=rotate
TICKVALUEROTATION=DIAGONAL
TICKVALUEPRIORITY=true)
)
yaxisopts=( OFFSETMIN=0
label="Score Values"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=1)
)
)
y2axisopts=( OFFSETMIN=0
label="Average Score"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=.5)
)
);
barchart x=visit_num y=score /
/* fillattrs=(color=CX4A7DB4 transparency=0.2)*/
outlineattrs=(color=CX4A7DB4 thickness=1)
barwidth=0.6
name="bars"
legendlabel="Score Values"
includemissinggroup=false
yaxis=y
BARLABEL=on
GROUP=trtpn
GROUPDISPLAY=cluster
OUTLINEATTRS=(thickness=0)
;
/* scatterplot x=visit_num y=score /*/
/* markerattrs=(symbol=square size=0)*/
/* datalabel=bar_count*/
/* datalabelposition=top*/
/* datalabelattrs=(*/
/* size=10pt */
/* weight=bold */
/* color=black*/
/* )*/
/* yaxis=y;*/
scatterplot x=visit_num y=avg /
markerattrs=(
symbol=circlefilled
size=8
color=CXFF7F0E
)
name="avg"
legendlabel="Average Score (Month 6 & 12)"
yaxis=y2;
seriesplot x=visit_num y=avg /
lineattrs=(
pattern=shortdash
color=CXFF7F0E
thickness=2
)
name="series"
legendlabel="Average Trend"
yaxis=y2;
/* Reference line to mark start of months */
*referenceline x=0.5 /
lineattrs=(pattern=solid color=lightgray thickness=1)
curvelabel="Baseline"
curvelabelposition=min;
/* Legend */
discretelegend "bars" "avg" "series" /
location=outside
halign=center
border=true
autoalign=(bottom);
endlayout;
endgraph;
end;
run;
/* Render the graph with dual axes */
proc sgrender data=bar_data template=bargraph_trt1_dual;
format score 4.0 avg 4.1 visit_num visitfmt.;
label score="Score Value"
avg="Average Score"
visit="Visit"
bar_count="Count";
run;
"why the " double score" bar coming first"
I don't understand what " double score" is . Do you want to display 2 before 1 ? Just reorder it .
proc sort data=bar_data;
by descending trtpn visit_num;
run;
"Also the extra line graph is it becaz the avg value retained"
Yes. I already set it missing in my code.
data monthly_score_trt1;
set monthly_score dummy;
if trtpn=2 then call missing(avg);
run;
Thank you for the solution. Apologies, Error on my part that the treatments were assigned in reverse. Got fixed. thanks again.
Hi @Ksharp ,
Is there a way I can add the back group after Month 3 in the graph?. I was able to get the background, but don't know how to start from a specific value on- x-axis
" I can add the back group after Month 3"
Do you mean background ?
Here is the code you can start with.
/* Create the monthly_score dataset */
data monthly_score;
length trtpn 8 visit $10 score 8 avg 8;
call streaminit(123);
do trtpn = 1 to 2;
do month = 1 to 12;
/* Create visit name */
visit = cats('Month', month);
score = floor(rand('uniform') * 6);
avg = .;
if month = 6 then do;
if trtpn = 1 then avg = 3.5;
else avg = 3.5 + (rand('uniform') - 0.5) * 0.4;
end;
else if month = 12 then do;
if trtpn = 1 then avg = 6.8;
else avg = 6.8 + (rand('uniform') - 0.5) * 0.4;
end;
if avg ne . then avg = round(avg, 0.1);
output;
end;
end;
drop month;
run;
/* Create dummy record for BL with avg=0 but score missing */
data dummy;
visit = "BL";
avg = 0;
trtpn = 1;
score = .;
run;
/* Create dataset with counts for trtpn=1 */
data monthly_score_trt1;
set monthly_score dummy;
if trtpn=2 then call missing(avg);
run;
proc sort data = monthly_score_trt1;
by trtpn visit;
run;
/* Create a format to display month names */
proc format;
value visitfmt
0 = " "
1 = "Month1"
2 = "Month2"
3 = "Month3"
4 = "Month4"
5 = "Month5"
6 = "Month6"
7 = "Month7"
8 = "Month8"
9 = "Month9"
10 = "Month10"
11 = "Month11"
12 = "Month12";
run;
/* Create dataset with numeric visit variable */
data bar_data;
set monthly_score_trt1;
by trtpn visit;
if visit = "BL" then visit_num = 0;
else visit_num = input(scan(visit, -1, 'Month'), 8.);
bar_count = score;
if visit = "BL" then bar_count = .;
max=ifn(trtpn=2 and visit_num>3,7,.); /*7 is the max value in Y axis*/
keep trtpn visit visit_num score avg bar_count max;
run;
proc sort data=bar_data;
by trtpn visit_num;
run;
ods path(prepend) work.templat(update);
/* Create template with dual y-axes */
proc template;
define statgraph bargraph_trt1_dual;
begingraph;
entrytitle "Bar Graph by Visit for School Group 1";
entrytitle "with Counts Displayed on Top";
layout overlay /
xaxisopts=( OFFSETMIN=0
label="Visit"
type=linear
linearopts=(
viewmin=1 viewmax=12
tickvaluelist=(1 2 3 4 5 6 7 8 9 10 11 12)
tickvalueformat=visitfmt.
TICKVALUEFITPOLICY=rotate
TICKVALUEROTATION=DIAGONAL
TICKVALUEPRIORITY=true)
)
yaxisopts=( OFFSETMIN=0 OFFSETMAX=0
label="Score Values"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=1)
)
)
y2axisopts=( OFFSETMIN=0 OFFSETMAX=0
label="Average Score"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=.5)
)
);
barchart x=visit_num y=max /
barwidth=1
name="other_bars"
yaxis=y
OUTLINEATTRS=(thickness=0)
DATATRANSPARENCY=0.6
;
barchart x=visit_num y=score /
/* fillattrs=(color=CX4A7DB4 transparency=0.2)*/
outlineattrs=(color=CX4A7DB4 thickness=1)
barwidth=0.6
name="bars"
legendlabel="Score Values"
includemissinggroup=false
yaxis=y
BARLABEL=on
GROUP=trtpn
GROUPDISPLAY=cluster
OUTLINEATTRS=(thickness=0)
;
/* scatterplot x=visit_num y=score /*/
/* markerattrs=(symbol=square size=0)*/
/* datalabel=bar_count*/
/* datalabelposition=top*/
/* datalabelattrs=(*/
/* size=10pt */
/* weight=bold */
/* color=black*/
/* )*/
/* yaxis=y;*/
scatterplot x=visit_num y=avg /
markerattrs=(
symbol=circlefilled
size=8
color=CXFF7F0E
)
name="avg"
legendlabel="Average Score (Month 6 & 12)"
yaxis=y2;
seriesplot x=visit_num y=avg /
lineattrs=(
pattern=shortdash
color=CXFF7F0E
thickness=2
)
name="series"
legendlabel="Average Trend"
yaxis=y2;
/* Reference line to mark start of months */
*referenceline x=0.5 /
lineattrs=(pattern=solid color=lightgray thickness=1)
curvelabel="Baseline"
curvelabelposition=min;
/* Legend */
discretelegend "bars" "avg" "series" /
location=outside
halign=center
border=true
autoalign=(bottom);
endlayout;
endgraph;
end;
run;
/* Render the graph with dual axes */
proc sgrender data=bar_data template=bargraph_trt1_dual;
format score 4.0 avg 4.1 visit_num visitfmt.;
label score="Score Value"
avg="Average Score"
visit="Visit"
bar_count="Count";
run;
An alternative way is using REFLINE statement.
/* Create template with dual y-axes */
proc template;
define statgraph bargraph_trt1_dual;
begingraph;
entrytitle "Bar Graph by Visit for School Group 1";
entrytitle "with Counts Displayed on Top";
layout overlay /
xaxisopts=( OFFSETMIN=0
label="Visit"
type=linear
linearopts=(
viewmin=1 viewmax=12
tickvaluelist=(1 2 3 4 5 6 7 8 9 10 11 12)
tickvalueformat=visitfmt.
TICKVALUEFITPOLICY=rotate
TICKVALUEROTATION=DIAGONAL
TICKVALUEPRIORITY=true)
)
yaxisopts=( OFFSETMIN=0 OFFSETMAX=0
label="Score Values"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=1)
)
)
y2axisopts=( OFFSETMIN=0 OFFSETMAX=0
label="Average Score"
linearopts=(
viewmin=0 viewmax=7
tickvaluesequence=(start=0 end=7 increment=.5)
)
);
REFERENCELINE X=4/lineattrs=(thickness=40) DATATRANSPARENCY=0.8 ;
REFERENCELINE X=5/lineattrs=(thickness=40) DATATRANSPARENCY=0.8 ;
REFERENCELINE X=6/lineattrs=(thickness=40) DATATRANSPARENCY=0.8 ;
REFERENCELINE X=7/lineattrs=(thickness=40) DATATRANSPARENCY=0.8 ;
REFERENCELINE X=8/lineattrs=(thickness=40) DATATRANSPARENCY=0.8 ;
REFERENCELINE X=9/lineattrs=(thickness=40) DATATRANSPARENCY=0.8 ;
REFERENCELINE X=10/lineattrs=(thickness=40) DATATRANSPARENCY=0.8 ;
REFERENCELINE X=11/lineattrs=(thickness=40) DATATRANSPARENCY=0.8 ;
REFERENCELINE X=12/lineattrs=(thickness=40) DATATRANSPARENCY=0.8 ;
barchart x=visit_num y=score /
/* fillattrs=(color=CX4A7DB4 transparency=0.2)*/
outlineattrs=(color=CX4A7DB4 thickness=1)
barwidth=0.6
name="bars"
legendlabel="Score Values"
includemissinggroup=false
yaxis=y
BARLABEL=on
GROUP=trtpn
GROUPDISPLAY=cluster
OUTLINEATTRS=(thickness=0)
;
/* scatterplot x=visit_num y=score /*/
/* markerattrs=(symbol=square size=0)*/
/* datalabel=bar_count*/
/* datalabelposition=top*/
/* datalabelattrs=(*/
/* size=10pt */
/* weight=bold */
/* color=black*/
/* )*/
/* yaxis=y;*/
scatterplot x=visit_num y=avg /
markerattrs=(
symbol=circlefilled
size=8
color=CXFF7F0E
)
name="avg"
legendlabel="Average Score (Month 6 & 12)"
yaxis=y2;
seriesplot x=visit_num y=avg /
lineattrs=(
pattern=shortdash
color=CXFF7F0E
thickness=2
)
name="series"
legendlabel="Average Trend"
yaxis=y2;
/* Reference line to mark start of months */
*referenceline x=0.5 /
lineattrs=(pattern=solid color=lightgray thickness=1)
curvelabel="Baseline"
curvelabelposition=min;
/* Legend */
discretelegend "bars" "avg" "series" /
location=outside
halign=center
border=true
autoalign=(bottom);
endlayout;
endgraph;
end;
run;
Thank you very much.
Nearly 200 sessions are now available on demand with the SAS Innovate Digital Pass.
Explore Now →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.