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

Hello all, 

I have made a plot looking like the below and i want to highlight were the middle 95% is (meaning approximately from -4 to +4 on the x axis. 

Is that a feature in proc sgplot ? 

 

 

lone0708_1-1650534887109.png

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

As discussed in the article, one way is to rescale the curve so that it becomes a density. If your data are equally spaced in X, you can get away with just rescaling the Y heights by dividing by the sum of heights. The following statements compute the (scaled) cumulative distribution and then shade the region that excludes the lower and upper alpha/2 proportion of the heights. That means it keeps the interior 1-alpha proportion:

 

/* compute sum and put it into macro variable */
proc sql;
select sum(y) into :sum
 from Have;
quit;
%put &=sum;

/* create the cumulative density variable */
data Cumul;
set Have;
cumul + y / ∑
run;

/* shade where the cumulitive density is greater than alpha/2
   and less than 1-alpha/2 */
data Want;
alpha = 0.05;  /* ask for 95% region */
set Cumul;
if cumul>=alpha/2  and cumul <=1-alpha/2 then 
   upper = y; 
else 
   upper = .;
run;
/* graph it */
proc sgplot data=Want;
   band x=x upper=upper lower=0;
   series x=x y=y/ datalabel markers;
run;

View solution in original post

10 REPLIES 10
Rick_SAS
SAS Super FREQ

Yes: Use the BAND statement.  For an example and discussion, see "Create a density curve with shaded tails."

 

That article shades the tails, whereas you want to shade the interior. For your problem, the solution will look like this:

data Have;
input x y;
datalines;
-14 0.5
-12 0.6
-10 0.6
-8 0.8
-6 1.2
-4 2.2
-2 4.5
0  17
2  5.4
4  1.9
6  1.4
8  2.1
10 1.4
12 1.3
14 1.4
; 

data Want;
set Have;
low  = -4;   /* lower value to shade */
high = 4;    /* upper value to shade */
if x>=low  and x <=high then 
   upper = y; 
else 
   upper = .;
drop low high;
run;

proc sgplot data=Want;
   band x=x upper=upper lower=0;
   series x=x y=y/ datalabel markers;
run;
lone0708
Fluorite | Level 6
Fantastic! Thanks 😊

If I want to exchange the -4, +4 with a specific proportion e.g. meaning the 95% of the proportion are within the band. How do I write that in the low/high statement?
Rick_SAS
SAS Super FREQ

As discussed in the article, one way is to rescale the curve so that it becomes a density. If your data are equally spaced in X, you can get away with just rescaling the Y heights by dividing by the sum of heights. The following statements compute the (scaled) cumulative distribution and then shade the region that excludes the lower and upper alpha/2 proportion of the heights. That means it keeps the interior 1-alpha proportion:

 

/* compute sum and put it into macro variable */
proc sql;
select sum(y) into :sum
 from Have;
quit;
%put &=sum;

/* create the cumulative density variable */
data Cumul;
set Have;
cumul + y / &sum;
run;

/* shade where the cumulitive density is greater than alpha/2
   and less than 1-alpha/2 */
data Want;
alpha = 0.05;  /* ask for 95% region */
set Cumul;
if cumul>=alpha/2  and cumul <=1-alpha/2 then 
   upper = y; 
else 
   upper = .;
run;
/* graph it */
proc sgplot data=Want;
   band x=x upper=upper lower=0;
   series x=x y=y/ datalabel markers;
run;
lone0708
Fluorite | Level 6
It seems to work beautifully!
but, I think I have a problem because my x values can be negative. Right now, the band stops at zero (and does not take the negative values into account).
Rick_SAS
SAS Super FREQ

Yes, sounds like you have a problem. My example handles negative X values without any problem, so be sure to study it carefully. The logic for setting up the points for the BAND statement depends only on the cumulative proportions, not on X.

lone0708
Fluorite | Level 6

Hi Rick, 

Hmm i cannot understand, why this code gives me a plot looking like this as its the proportion around 0 i need to be shaded. Maybe you can help me out ?

 

image.png

 

Skærmbillede 2022-04-27 kl. 20.52.06.png

Rick_SAS
SAS Super FREQ

Try alpha=0.05 instead of alpha=0.5.

lone0708
Fluorite | Level 6
Hmm, it is still the same.
Rick_SAS
SAS Super FREQ

I don't know. However, I suggest that you avoid overwriting the ABC data set. If you run this code a second time, it will overwrite the ABC data, which will surely corrupt the results. Don't use 
data ABC;

set CUMUL;

when CUMUL was generated from ABC.

lone0708
Fluorite | Level 6
And that fixed the problem…… THANKS ! 😊

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
  • 10 replies
  • 1089 views
  • 0 likes
  • 2 in conversation