BookmarkSubscribeRSS Feed
Riis
Fluorite | Level 6

Hi all,

 

I want to create a forest plot of the estimates and 95% confidence limits in the dataset forestplot:

 

proc format;
value group
1='Age'
2='<60 years'
3='>=60 years'
4='Sex'
5='Females'
6='Males'
7='Diabetes mellitus'
8='No'
9='Yes'
10='Hypertension'
11='No'
12='Yes'
13='Active smoking'
14='No'
15='Yes';
run;

data forestplot;
input group $1-18 est low up indent plot;
format est low up 5.1;
id=_n_;
idf=_n_;
format idf group.;
datalines;
Age                 .     .     .  . 1
<60 years         13.2  12.8  13.7 1 1
>=60 years        15.5  13.2  18.1 1 1
Sex                 .     .     .  . 1
Females           13.8  13.3  14.4 1 1
Males             14.7  14.1  15.4 1 1
Diabetes mellitus   .     .     .  . 2
No                14.1  13.6  14.5 1 2
Yes               16.4  14.7  18.1 1 2
Hypertension        .     .     .  . 3
No                11.4  10.9  11.9 1 3
Yes               18.1  17.4  18.8 1 3
Active smoking      .     .     .  . 4
No                13.5  13.1  14.0 1 4
Yes               16.1  15.1  17.0 1 4
;
run;

 

This code almost does the trick:

 

%let gpath=C:\SAS\;
ods _all_ close; 
ods listing;
ods listing gpath="&gpath" style=journal image_dpi=200;

ods graphics / reset=index imagename="Forest plot" imagefmt=png border=off width=400px height=400px;
title1 "Proportion (%) (95% CI)";
proc sgplot data=forestplot noautolegend nocycleattrs nowall noborder; 
	scatter y=group x=est / markerattrs=graphdata2(symbol=squarefilled) xerrorupper=up xerrorlower=low errorbarattrs=(color=black);
	yaxistable group / y=group location=inside position=left labelattrs=(size=7) indentweight=indent label='Category';
	refline 10 20 30 / axis=x lineattrs=(pattern=shortdash) transparency=0.5 noclip;
	xaxis max=30 minor display=(nolabel)  valueattrs=(size=7);
  yaxis display=none fitpolicy=none reverse;
run;

 

Except that the estimates are grouped for the categories ‘No’ and ‘Yes’:

Forest plot.png

To work around this, I used the id variable, which plots only a single estimate per row:

 

ods graphics / reset=index imagename="Forest plot raw" imagefmt=png border=off width=400px height=400px;
title1 "Proportion (%) (95% CI)";
proc sgplot data=forestplot noautolegend nocycleattrs nowall noborder; 
	scatter y=id x=est / markerattrs=graphdata2(symbol=squarefilled) xerrorupper=up xerrorlower=low errorbarattrs=(color=black);
	yaxistable id / y=id location=inside position=left labelattrs=(size=7) indentweight=indent label='Category';
	refline 10 20 30 / axis=x lineattrs=(pattern=shortdash) transparency=0.5 noclip;
	xaxis max=30 minor display=(nolabel)  valueattrs=(size=7);
  yaxis display=none fitpolicy=none reverse;
run;

 

 

Forest plot raw.png

Then it should be easy to use a format to get the text label instead of the id numbers:

 

ods graphics / reset=index imagename="Forest plot formatted" imagefmt=png border=off width=400px height=400px;
title1 "Proportion (%) (95% CI)";
proc sgplot data=forestplot noautolegend nocycleattrs nowall noborder; 
	scatter y=id x=est / markerattrs=graphdata2(symbol=squarefilled) xerrorupper=up xerrorlower=low errorbarattrs=(color=black);
	yaxistable id / y=id location=inside position=left labelattrs=(size=7) indentweight=indent label='Category';
	refline 10 20 30 / axis=x lineattrs=(pattern=shortdash) transparency=0.5 noclip;
	xaxis max=30 minor display=(nolabel)  valueattrs=(size=7);
  yaxis display=none fitpolicy=none reverse;
	format id group.; *Format added;
run;

 

But then the format isn’t displayed as expected:

Forest plot formatted.png

 

Anyone who knows what to do?

 

Thanks in advance!

 

 

4 REPLIES 4
Reeza
Super User

I think I got around this by adding invisible characters to the No/Yes categories so they are actually different and will get grouped individually but still look the same.

Riis
Fluorite | Level 6

Thanks Reeza! It works but there must be another way to get the format printed? I have many No/Yes-categories so I will have to insert many invisible characters...

ballardw
Super User

See if this plot is closer to what you want:

proc format;
value group
1='Age'
2='<60 years'
3='>=60 years'
4='Sex'
5='Females'
6='Males'
7='Diabetes mellitus'
8='No'
9='Yes'
10='Hypertension'
11='No'
12='Yes'
13='Active smoking'
14='No'
15='Yes';
run;

data forestplot;
input group $1-18 est low up indent plot;
format est low up 5.1;
id=_n_;
idf=_n_;
format idf group.;
datalines;
Age                 .     .     .  . 1
<60 years         13.2  12.8  13.7 1 1
>=60 years        15.5  13.2  18.1 1 1
Sex                 .     .     .  . 1
Females           13.8  13.3  14.4 1 1
Males             14.7  14.1  15.4 1 1
Diabetes mellitus   .     .     .  . 2
No                14.1  13.6  14.5 1 2
Yes               16.4  14.7  18.1 1 2
Hypertension        .     .     .  . 3
No                11.4  10.9  11.9 1 3
Yes               18.1  17.4  18.8 1 3
Active smoking      .     .     .  . 4
No                13.5  13.1  14.0 1 4
Yes               16.1  15.1  17.0 1 4
;
run;

 

I am not sure if you actually want the axis table in the final result or were just using that to show a desired order.

Riis
Fluorite | Level 6

Yes, I need the table in the final plot.

Is there a proc sgplot missing from your reply?

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


Register now!

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 1383 views
  • 3 likes
  • 3 in conversation