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

Hello all. I am trying to recreate a figure much like the barchart shown in "A" below. I am having problems with A) adding multiple text fields (which exist as variables) into the plot
B) adding any text fields near the plot when including CI.

Does anyone know if this is possible?nejmoa2402309_f1.jpg

 

 

If I don't include the confidence intervals, the datalabel will put one number near the data. However, if it's included datalabel acts like xaxistable.
I've included some dummy data using the cars dataset from sashelp to run the example code I've made so far. Any input is appreciated!

data cars;
set sashelp.cars;
pvalue = 0.001;
ucl = Invoice+(Invoice*.05);
lcl = invoice-(Invoice*.05);
if _N_ LE 6;
if _N_ in (1,3,5) then odds =1;
else odds = 0;
if _N_ in (1,2) then parameter = "Group A";
else if _N_ in (3,4)  then parameter = "Group B";
else parameter = "Group C";
run;

proc sgplot data=cars;
   vbarparm category=parameter response=invoice 
/  groupdisplay=cluster group=odds 
 limitlower=lcl limitupper=ucl LIMITATTRS=(color=darkslategrey) datalabel=invoice;
 styleattrs datacolors=(green purple) datacontrastcolors=(green purple);

  yaxis label = "Invoice" display=(noline noticks) grid;
  xaxis display=(nolabel); 
run;
1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User
data a;
input category $ group $ v lower upper p $;
if group='Ole' then v1=v;
if group='Ola' then v2=v;
max=max(v,lower,upper,0);
cards;
Trig Ole -49.3 -52.3 -46.2 p<0.01
Trig Ola -64.3 -68.3 -58.2 p<0.01
APOC Ole -69.3 -75.3 -60.2 p<0.01
APOC Ola -79.3 -85.3 -68.2 p<0.01
VLDL Ole  49.3  42.3  55.2 p<0.01
VLDL Ola  40.3  35.3  48.2 p<0.01
;
proc sgplot data=a;
 styleattrs datacolors=(yellow gold) ; 

   vbarparm category=category response=v1 
/fillattrs=(color=white)  groupdisplay=cluster group=group  nooutline  datalabel=v1 discreteoffset=-0.1;
   vbarparm category=category response=v2 
/fillattrs=(color=white)  groupdisplay=cluster group=group  nooutline  datalabel=v2 discreteoffset=0.1;
scatter x=category y=max/group=group groupdisplay=cluster markerattrs=(size=0)
 datalabel=p datalabelpos=top datalabelattrs=(color=black) labelstrip;

   vbarparm category=category response=v 
/  groupdisplay=cluster group=group  nooutline
 limitlower=lower limitupper=upper LIMITATTRS=(color=black) name='x' ;
keylegend 'x'/location=inside position=top;
xaxis display=(nolabel);
run;

Ksharp_0-1754630984368.png

 

 

 


/*************************************/
data b;
infile cards truncover;
input group day v lower upper text $20.;
cards;
1 0 200 180 210
1 1 150 120 160
1 2 120 110 128
1 3 110 102 118
1 6 109 101 112
1 10 105 100 110
2 0 210 190 220
2 1 160 130 170
2 2 110 120 138
2 3 120 112 128
2 6 119 111 122
2 10 115 110 120
. 8 124   .   .    TreatA|(n=26)
. 8 102   .   .    TreatB|(n=26)
;
proc sgplot data=b;
series x=day y=v/group=group nomissinggroup;
scatter x=day y=v/group=group nomissinggroup yerrorupper=upper yerrorlower=lower markerattrs=(symbol=circlefilled);
xaxis type=linear values=(0 to 10 by 1)  display=(nolabel noticks) 
valuesdisplay=('Baseline' 'Day28' 'Day56' 'Day84' '' ''  'Day252' '' '' '' 'Day308');
text x=day y=v text=text/strip contributeoffsets=none splitchar='|' splitpolicy=splitalways;
run;


Ksharp_1-1754631011785.png

 

View solution in original post

4 REPLIES 4
DanH_sas
SAS Super FREQ

The best way to do this is to use a TEXT plot. Here is an example using your test program. Notice the extra "position" column added to your data:

data cars;
set sashelp.cars;
pvalue = 0.001;
ucl = Invoice+(Invoice*.05);
lcl = invoice-(Invoice*.05);
if _N_ LE 6;
if _N_ in (1,3,5) then odds =1;
else odds = 0;
if _N_ in (1,2) then parameter = "Group A";
else if _N_ in (3,4)  then parameter = "Group B";
else parameter = "Group C";
/* Set the text position based on the odds value */
if odds = 0 then position="topright";
else position="topleft"; 
run;

proc sgplot data=cars;
   vbarparm category=parameter response=invoice 
/  groupdisplay=cluster group=odds 
 limitlower=lcl limitupper=ucl LIMITATTRS=(color=darkslategrey) datalabel=invoice;
 styleattrs datacolors=(green purple) datacontrastcolors=(green purple);
 text x=parameter y=invoice text=invoice / position=position group=odds groupdisplay=cluster;

  yaxis label = "Invoice" display=(noline noticks) grid;
  xaxis display=(nolabel); 
run;

DanH_sas_0-1754580930934.png

 

elg
Fluorite | Level 6 elg
Fluorite | Level 6
Thanks Dan. Is there a way to show the pvalue as well (bonus on an angle like the original)?

Also is there a way to remove it from the text at the bottom?
DanH_sas
SAS Super FREQ

First of all, the DATALABEL option putting the values under the bars to prevent collision with the CI limits. Since you will be using TEXT plots, just remove that option.

 

As for the p-value. you can also do that with a TEXT plot. I add the additional data and code to the previous example:

data cars;
set sashelp.cars;
length pvalue_str $ 7;
pvalue = 0.001;
ucl = Invoice+(Invoice*.05);
lcl = invoice-(Invoice*.05);
if _N_ LE 6;
if _N_ in (1,3,5) then odds =1;
else odds = 0;
if _N_ in (1,2) then parameter = "Group A";
else if _N_ in (3,4)  then parameter = "Group B";
else parameter = "Group C";
/* Set the text position based on the odds value */
if odds = 0 then position="topright";
else position="topleft"; 
/* Add example  p-values */
rotate=0;
pvalue_str="";
if _N_ in (3,4) then do;
   rotate=45;
   pvalue_str="P<" || put(pvalue, F5.3);
end;
run;

proc sgplot data=cars;
   vbarparm category=parameter response=invoice 
/  groupdisplay=cluster group=odds 
 limitlower=lcl limitupper=ucl LIMITATTRS=(color=darkslategrey);
 styleattrs datacolors=(green purple) datacontrastcolors=(green purple);
 text x=parameter y=invoice text=invoice / position=position group=odds groupdisplay=cluster;
 text x=parameter y=ucl text=pvalue_str / position=topright group=odds groupdisplay=cluster rotate=rotate;

  yaxis label = "Invoice" display=(noline noticks) grid offsetmin=0;
  xaxis display=(nolabel); 
run;

DanH_sas_0-1754587313333.png

Notice that I added OFFSETMIN=0 to the YAXIS in this case, because I knew all bar were positive, and I did not want the bars to "float" due the TEXT plot values. In your case, you have positive and negative values, so that should be removed. There is also an option on the TEXT plot called CONTRIBUTEOFFSETS=none that will disable the TEXT plot from being considered for axis offset calculations. It's a useful option, but I do not think it is needed for your case.

Ksharp
Super User
data a;
input category $ group $ v lower upper p $;
if group='Ole' then v1=v;
if group='Ola' then v2=v;
max=max(v,lower,upper,0);
cards;
Trig Ole -49.3 -52.3 -46.2 p<0.01
Trig Ola -64.3 -68.3 -58.2 p<0.01
APOC Ole -69.3 -75.3 -60.2 p<0.01
APOC Ola -79.3 -85.3 -68.2 p<0.01
VLDL Ole  49.3  42.3  55.2 p<0.01
VLDL Ola  40.3  35.3  48.2 p<0.01
;
proc sgplot data=a;
 styleattrs datacolors=(yellow gold) ; 

   vbarparm category=category response=v1 
/fillattrs=(color=white)  groupdisplay=cluster group=group  nooutline  datalabel=v1 discreteoffset=-0.1;
   vbarparm category=category response=v2 
/fillattrs=(color=white)  groupdisplay=cluster group=group  nooutline  datalabel=v2 discreteoffset=0.1;
scatter x=category y=max/group=group groupdisplay=cluster markerattrs=(size=0)
 datalabel=p datalabelpos=top datalabelattrs=(color=black) labelstrip;

   vbarparm category=category response=v 
/  groupdisplay=cluster group=group  nooutline
 limitlower=lower limitupper=upper LIMITATTRS=(color=black) name='x' ;
keylegend 'x'/location=inside position=top;
xaxis display=(nolabel);
run;

Ksharp_0-1754630984368.png

 

 

 


/*************************************/
data b;
infile cards truncover;
input group day v lower upper text $20.;
cards;
1 0 200 180 210
1 1 150 120 160
1 2 120 110 128
1 3 110 102 118
1 6 109 101 112
1 10 105 100 110
2 0 210 190 220
2 1 160 130 170
2 2 110 120 138
2 3 120 112 128
2 6 119 111 122
2 10 115 110 120
. 8 124   .   .    TreatA|(n=26)
. 8 102   .   .    TreatB|(n=26)
;
proc sgplot data=b;
series x=day y=v/group=group nomissinggroup;
scatter x=day y=v/group=group nomissinggroup yerrorupper=upper yerrorlower=lower markerattrs=(symbol=circlefilled);
xaxis type=linear values=(0 to 10 by 1)  display=(nolabel noticks) 
valuesdisplay=('Baseline' 'Day28' 'Day56' 'Day84' '' ''  'Day252' '' '' '' 'Day308');
text x=day y=v text=text/strip contributeoffsets=none splitchar='|' splitpolicy=splitalways;
run;


Ksharp_1-1754631011785.png

 

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

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
  • 415 views
  • 2 likes
  • 3 in conversation