BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Awesome1
Fluorite | Level 6

Hi all!

 

While looking for a way to graphically present results from McNemar's test, I found the attached figure (from https://fmcna.com/insights/white-papers/effectiveness-velphoro-patients-chronic-dialysis/).

 

Is there a way to make this plot in Unix SAS v9.4 (TS1M5)? I thought it would be easy enough - create a cluster bar plot using precomputed data (to ensure the proper denominator is used) and an annotated dataset for the arrows and text. However, it has proven much more difficult than that.

 

I could not figure out how to use pre-computed proportions in the vbarparm statement to make the simple bar plot nor how to generate coordinates for the arrows/text in the annotated dataset given the xaxis is categorical and clustered. 

 

Can anyone offer assistance? I'd greatly appreciate it!

 

Best,

Amanda

1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User

How about this one ?

 

x.png

 

 

data have;
infile cards truncover;
input id sex $ per p l h v : $10. w pp;
format w percent7.0;
cards;
1 F 0.3 .  . . . . .
1 M 0.7 0.7 0.3 0.7 —————— 0.4 0.72
2 F 0.4  . . . . . .
2 M 0.6 0.6 0.4 0.6 —————— 0.2 0.62
;

proc sgplot data=have;
vbarparm category=id response=per /group=sex  groupdisplay=cluster;
scatter x=id y=p/ markerchar=v discreteoffset=-0.09 ;
scatter x=id y=pp/ markerchar=w discreteoffset=-0.2 markercharattrs=(size=10) ;
scatter x=id y=p/ markerattrs=(symbol=trianglerightfilled color=black size=10) 
discreteoffset=-0.02 ;
highlow x=id low=l high=h/discreteoffset=-0.2 lineattrs=(color=black) lowcap=filledarrow;
run;

View solution in original post

8 REPLIES 8
Jay54
Meteorite | Level 14

I suggest this can be made by layering a HighLow plot (TYPE=LINE) over a Cluster Grouped VBARPARM.  This will get you 99% there using a cluster grouped HighLow with LOWCAP, HIGHCAP and HIGHLABEL options.  For the HighLow, the blue group values can be missing.

Awesome1
Fluorite | Level 6

Thanks for the response! Much appreciated. I'll use this during formatting.

DanH_sas
SAS Super FREQ

Yes, this can be done. There are two keys to to placing the arrows correctly:

1. Use the category data value to find the primary position long the axis for the arrows.

2. Use DISCRETEOFFSET to offset the ARROWS left or right of that data position.

 

Let me know if you need more explanation.

Awesome1
Fluorite | Level 6

I see where Ksharp used these in their code. Thanks for the response and offer of additional assistance! Greatly appreciated 🙂

Ksharp
Super User

How about this one ?

 

x.png

 

 

data have;
infile cards truncover;
input id sex $ per p l h v : $10. w pp;
format w percent7.0;
cards;
1 F 0.3 .  . . . . .
1 M 0.7 0.7 0.3 0.7 —————— 0.4 0.72
2 F 0.4  . . . . . .
2 M 0.6 0.6 0.4 0.6 —————— 0.2 0.62
;

proc sgplot data=have;
vbarparm category=id response=per /group=sex  groupdisplay=cluster;
scatter x=id y=p/ markerchar=v discreteoffset=-0.09 ;
scatter x=id y=pp/ markerchar=w discreteoffset=-0.2 markercharattrs=(size=10) ;
scatter x=id y=p/ markerattrs=(symbol=trianglerightfilled color=black size=10) 
discreteoffset=-0.02 ;
highlow x=id low=l high=h/discreteoffset=-0.2 lineattrs=(color=black) lowcap=filledarrow;
run;
Awesome1
Fluorite | Level 6
data test;
infile cards truncover;
input id time $ per p l h v : $10. w pp;
format per p l h w pp PERCENTN8.1;
cards;
1 Before .473 . . . . . .
1 After .379 .473 .379 .473 ——— -.2 .493
2 Before .778 . . . . . .
2 After .619 .778 .619 .778 ——— -.204 .798 
;

proc sgplot data=test;
vbarparm category=id response=per /group=time  groupdisplay=cluster;
scatter x=id y=p/ markerchar=v discreteoffset=0.09 ;  ** top line **;
scatter x=id y=p/ markerattrs=(symbol=triangleleftfilled color=black size=10) discreteoffset=0.02 ;  ** arrow to the right **;
scatter x=id y=pp/ markerchar=w discreteoffset=0.2 markercharattrs=(size=10) ;  ** percent label **;
highlow x=id low=l high=h/discreteoffset=0.2 lineattrs=(color=black) lowcap=filledarrow;	** arrow pointing down **;
yaxis offsetmin=0;
run;

Annotated Cluster Bar Plot using SGPLOT-results.JPG

 

I made some minor modifications to fit my data but this was great! 

Thanks, Ksharp!! 

ballardw
Super User

Which is more important: keeping the order of the Vbars or having the range indicator on a specific side?

 

The example you show has ALL of the larger values in one of the subgroups for the X-axis variable. What do you want to have for appearance if the larger value changes for some groups?

Do want the range indicator to always be on the left (as shown) or keep the bars in the same order and have the range indicator move to the right side of the pair as needed?

Awesome1
Fluorite | Level 6

Thanks for responding.

 

I think keeping the order of the vbars will make it easier to take in with multiple before/after tests so I'd say it is more important. I definitely want to keep the bars in the same order and have the range indicator move to the right side of the pair as needed!

 

The image provided just happened to have increases after the intervention but my data has reductions in proportions. I was able to modify the code Ksharp provided to capture this. I'm working on making it more automated but it is a great start.

 

If you have any ideas on how to best do so, I'd love to hear them!

 

Thanks again for your response!

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 8 replies
  • 1502 views
  • 4 likes
  • 5 in conversation