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
How about this one ?
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;
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.
Thanks for the response! Much appreciated. I'll use this during formatting.
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.
I see where Ksharp used these in their code. Thanks for the response and offer of additional assistance! Greatly appreciated 🙂
How about this one ?
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;
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;
I made some minor modifications to fit my data but this was great!
Thanks, Ksharp!!
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?
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!
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: