-->
BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
MFraga
Quartz | Level 8

In the sgplot below, I am trying to create a graph that draws attention to "North America" and coding it so that when I update the data next year, even if the order by "growth_rate" (which is defined by proc sort) changes (i.e., North America is no longer the region with the worst growth rate in 2025), every time the horizontal bars are created for North America they will have the respective reddish colors chosen in the data step "have3" and all other regions will have the bluish colors chosen in the data step "have3".

Could someone help me understand why SAS is not correctly applying the colors defined for the variable color (and instead is using shades of gray that I have not indicated)?


Also how to make my code works as I intend? In other words, I am trying to create a graph that always draws attention to North America by assigning it a unique colors. Any insight is welcome!

Here is my code:

 

data have;
input code region &$20. growth_rate year;
datalines;
0 North America -5.92 2020
0 North America -2.18 2021
0 North America -7.47 2022
0 North America -2.17 2023
0 North America -9.64 2024
1 South America 0.36 2020
1 South America 2.69 2021
1 South America -8.13 2022
1 South America 1.22 2023
1 South America -1.34 2024
2 Asia -1.53 2020
2 Asia 2.18 2021
2 Asia 5.64 2022
2 Asia 6.80 2023
2 Asia 8.70 2024
3 Europe -9.68 2020
3 Europe 3.91 2021
3 Europe 5.48 2022
3 Europe 3.52 2023
3 Europe 3.69 2024
4 Africa 3.29 2020
4 Africa 7.97 2021
4 Africa 2.48 2022
4 Africa 7.36 2023
4 Africa 1.31 2024
5 Oceania 8.00 2020
5 Oceania -6.05 2021
5 Oceania 6.91 2022
5 Oceania -1.09 2023
5 Oceania -7.46 2024
;
run;

 

proc sort data=have(where=(year=2024)) out=temp;
by descending growth_rate ;
run;

 

data fmt;
set temp(rename=(region=start));
retain fmtname 'fmt' type 'c';
length label $ 80;
label=repeat(' ',_n_)||strip(start);
keep fmtname type start label;
run;

 

proc format cntlin=fmt;
run;

 

data have2;
set have;
_region=put(region,$fmt32.);
if region="North America" then call symput('NorthAmerica',_region);
run;

 

data have3;
set have2;
if _region="North America" then do;
if year=2020 then color="#f7ebde";
else if year=2021 then color="#efdbc6";
else if year=2022 then color="#e1ca9e";
else if year=2023 then color="#d6ae6b";
else if year=2024 then color="#b4771f";
end;
if _region NE "North America" then do;
if year=2020 then color="#deebf7";
else if year=2021 then color="#c6dbef";
else if year=2022 then color="#9ecae1";
else if year=2023 then color="#6baed6";
else if year=2024 then color="#1f77b4";
end;
run;

 

%sganno
data sganno;
%SGTEXT(LABEL="North America",TEXTWEIGHT="BOLD",TEXTCOLOR="RED",TEXTSIZE=10, FILLCOLOR="white",FILLTRANSPARENCY=0,WIDTH=40,Y1SPACE="DATAVALUE",X1SPACE="LAYOUTPERCENT",YC1="&NorthAmerica.",X1=6 )
run;

 

proc sgplot data=have3 sganno=sganno;
title "Growth rate";
styleattrs datacolors=(color);
hbar _region / response=growth_rate group=year
groupdisplay=cluster
clusterwidth=0.9
datalabel DATALABELFITPOLICY=NONE
datalabelattrs=(size=8pt)
barwidth=1 nooutline
transparency=0 dataskin=none;

xaxis display=(nolabel) min=-12 max=12;
yaxis display=(nolabel) colorbands=even ;
run;

 

1 ACCEPTED SOLUTION

Accepted Solutions
DanH_sas
SAS Super FREQ

I think the easiest way for this case here is to use a range attributes map. The key is mapping the region/year combinations into a single numeric value that you can use in the attributes map.

 

data have;
input code region $ 3-16 growth_rate year;
datalines;
0 North America -5.92 2020
0 North America -2.18 2021
0 North America -7.47 2022
0 North America -2.17 2023
0 North America -9.64 2024
1 South America 0.36 2020
1 South America 2.69 2021
1 South America -8.13 2022
1 South America 1.22 2023
1 South America -1.34 2024
2 Asia          -1.53 2020
2 Asia          2.18 2021
2 Asia          5.64 2022
2 Asia          6.80 2023
2 Asia          8.70 2024
3 Europe        -9.68 2020
3 Europe        3.91 2021
3 Europe        5.48 2022
3 Europe        3.52 2023
3 Europe        3.69 2024
4 Africa        3.29 2020
4 Africa        7.97 2021
4 Africa        2.48 2022
4 Africa        7.36 2023
4 Africa        1.31 2024
5 Oceania       8.00 2020
5 Oceania       -6.05 2021
5 Oceania       6.91 2022
5 Oceania       -1.09 2023
5 Oceania       -7.46 2024
;
run;

proc sort data=have(where=(year=2024)) out=temp;
by descending growth_rate ;
run;

data fmt;
set temp(rename=(region=start));
retain fmtname 'fmt' type 'c';
length label $ 80;
label=repeat(' ',_n_)||strip(start);
keep fmtname type start label;
run;

proc format cntlin=fmt;
run;

data have2;
set have;
_region=put(region,$fmt32.);
if region="North America" then call symput('NorthAmerica',_region);
run;

data have3;
set have2;
if region="North America" then do;
if year=2020 then color=1;
else if year=2021 then color=2;
else if year=2022 then color=3;
else if year=2023 then color=4;
else if year=2024 then color=5;
end;
if region NE "North America" then do;
if year=2020 then color=6;
else if year=2021 then color=7;
else if year=2022 then color=8;
else if year=2023 then color=9;
else if year=2024 then color=10;
end;
run;

data attrmap;
retain ID "barcolors" altcolor "black";
input min $ max $ color $;
datalines;
1  1  cxf7ebde
2  2  cxefdbc6
3  3  cxe1ca9e
4  4  cxd6ae6b
5  5  cxb4771f
6  6  cxdeebf7
7  7  cxc6dbef
8  8  cx9ecae1
9  9  cx6baed6
10 10 cx1f77b4
;
run;

data sganno;
%sganno
%SGTEXT(LABEL="North America",TEXTWEIGHT="BOLD",TEXTCOLOR="RED",TEXTSIZE=10, FILLCOLOR="white",FILLTRANSPARENCY=0,WIDTH=40,Y1SPACE="DATAVALUE",X1SPACE="LAYOUTPERCENT",YC1="&NorthAmerica.",X1=6 )
run;

proc sgplot data=have3 sganno=sganno rattrmap=attrmap noautolegend;
title "Growth rate";
hbar _region / response=growth_rate group=year colorresponse=color rattrid=barcolors
groupdisplay=cluster
clusterwidth=0.9
datalabel DATALABELFITPOLICY=NONE
datalabelattrs=(size=8pt)
barwidth=1 nooutline
transparency=0 dataskin=none;
xaxis display=(nolabel) min=-12 max=12;
yaxis display=(nolabel) colorbands=even ;
run; 

 

View solution in original post

6 REPLIES 6
DanH_sas
SAS Super FREQ

I think the easiest way for this case here is to use a range attributes map. The key is mapping the region/year combinations into a single numeric value that you can use in the attributes map.

 

data have;
input code region $ 3-16 growth_rate year;
datalines;
0 North America -5.92 2020
0 North America -2.18 2021
0 North America -7.47 2022
0 North America -2.17 2023
0 North America -9.64 2024
1 South America 0.36 2020
1 South America 2.69 2021
1 South America -8.13 2022
1 South America 1.22 2023
1 South America -1.34 2024
2 Asia          -1.53 2020
2 Asia          2.18 2021
2 Asia          5.64 2022
2 Asia          6.80 2023
2 Asia          8.70 2024
3 Europe        -9.68 2020
3 Europe        3.91 2021
3 Europe        5.48 2022
3 Europe        3.52 2023
3 Europe        3.69 2024
4 Africa        3.29 2020
4 Africa        7.97 2021
4 Africa        2.48 2022
4 Africa        7.36 2023
4 Africa        1.31 2024
5 Oceania       8.00 2020
5 Oceania       -6.05 2021
5 Oceania       6.91 2022
5 Oceania       -1.09 2023
5 Oceania       -7.46 2024
;
run;

proc sort data=have(where=(year=2024)) out=temp;
by descending growth_rate ;
run;

data fmt;
set temp(rename=(region=start));
retain fmtname 'fmt' type 'c';
length label $ 80;
label=repeat(' ',_n_)||strip(start);
keep fmtname type start label;
run;

proc format cntlin=fmt;
run;

data have2;
set have;
_region=put(region,$fmt32.);
if region="North America" then call symput('NorthAmerica',_region);
run;

data have3;
set have2;
if region="North America" then do;
if year=2020 then color=1;
else if year=2021 then color=2;
else if year=2022 then color=3;
else if year=2023 then color=4;
else if year=2024 then color=5;
end;
if region NE "North America" then do;
if year=2020 then color=6;
else if year=2021 then color=7;
else if year=2022 then color=8;
else if year=2023 then color=9;
else if year=2024 then color=10;
end;
run;

data attrmap;
retain ID "barcolors" altcolor "black";
input min $ max $ color $;
datalines;
1  1  cxf7ebde
2  2  cxefdbc6
3  3  cxe1ca9e
4  4  cxd6ae6b
5  5  cxb4771f
6  6  cxdeebf7
7  7  cxc6dbef
8  8  cx9ecae1
9  9  cx6baed6
10 10 cx1f77b4
;
run;

data sganno;
%sganno
%SGTEXT(LABEL="North America",TEXTWEIGHT="BOLD",TEXTCOLOR="RED",TEXTSIZE=10, FILLCOLOR="white",FILLTRANSPARENCY=0,WIDTH=40,Y1SPACE="DATAVALUE",X1SPACE="LAYOUTPERCENT",YC1="&NorthAmerica.",X1=6 )
run;

proc sgplot data=have3 sganno=sganno rattrmap=attrmap noautolegend;
title "Growth rate";
hbar _region / response=growth_rate group=year colorresponse=color rattrid=barcolors
groupdisplay=cluster
clusterwidth=0.9
datalabel DATALABELFITPOLICY=NONE
datalabelattrs=(size=8pt)
barwidth=1 nooutline
transparency=0 dataskin=none;
xaxis display=(nolabel) min=-12 max=12;
yaxis display=(nolabel) colorbands=even ;
run; 

 

DanH_sas
SAS Super FREQ

Oh, I forgot to add the NOAUTOLEGEND option to the SGPLOT statement. You'll want that to get rid of the gradient legend on the right.

DanH_sas
SAS Super FREQ

Nevermind, I was able to edit the post 🙂

Ksharp
Super User

1)

Same as Danh_sas 's code, other than him ,I used DATTRMAP= option:

 

data have;
input code region &$20. growth_rate year;
datalines;
0 North America  -5.92 2020
0 North America  -2.18 2021
0 North America  -7.47 2022
0 North America  -2.17 2023
0 North America  -9.64 2024
1 South America  0.36 2020
1 South America  2.69 2021
1 South America  -8.13 2022
1 South America  1.22 2023
1 South America  -1.34 2024
2 Asia  -1.53 2020
2 Asia  2.18 2021
2 Asia  5.64 2022
2 Asia  6.80 2023
2 Asia  8.70 2024
3 Europe  -9.68 2020
3 Europe  3.91 2021
3 Europe  5.48 2022
3 Europe  3.52 2023
3 Europe  3.69 2024
4 Africa  3.29 2020
4 Africa  7.97 2021
4 Africa  2.48 2022
4 Africa  7.36 2023
4 Africa  1.31 2024
5 Oceania  8.00 2020
5 Oceania  -6.05 2021
5 Oceania  6.91 2022
5 Oceania  -1.09 2023
5 Oceania  -7.46 2024
;
run;

 

proc sort data=have(where=(year=2024)) out=temp;
by descending growth_rate ;
run;

 

data fmt;
set temp(rename=(region=start));
retain fmtname 'fmt' type 'c';
length label $ 80;
label=repeat(' ',_n_)||strip(start);
keep fmtname type start label;
run;

 

proc format cntlin=fmt;
run;

 

data have2;
set have;
_region=put(region,$fmt32.);
if region="North America" then call symput('NorthAmerica',_region);
run;

 

data have3;
set have2;
if strip(_region)="North America" then year=10*year ;
run;

data dattramp;
input id $ value fillcolor $;
cards;
x 20200 #f7ebde
x 20210 #efdbc6
x 20220 #e1ca9e
x 20230 #d6ae6b
x 20240 #b4771f
x 2020 #deebf7
x 2021 #c6dbef
x 2022 #9ecae1
x 2023 #6baed6
x 2024 #1f77b4
;



%sganno
data sganno;
%SGTEXT(LABEL="North America",TEXTWEIGHT="BOLD",TEXTCOLOR="RED",TEXTSIZE=10, FILLCOLOR="white",FILLTRANSPARENCY=0,WIDTH=40,Y1SPACE="DATAVALUE",X1SPACE="LAYOUTPERCENT",YC1="&NorthAmerica.",X1=6 )
run;

 

proc sgplot data=have3 sganno=sganno dattrmap=dattramp noautolegend;
title "Growth rate";
*styleattrs datacolors=(color);
hbar _region / response=growth_rate group=year attrid=x
groupdisplay=cluster
clusterwidth=0.9
datalabel DATALABELFITPOLICY=NONE
datalabelattrs=(size=8pt)
barwidth=1 nooutline
transparency=0 dataskin=none;

xaxis display=(nolabel) min=-12 max=12;
yaxis display=(nolabel) colorbands=even colorbandsattrs=(transparency=0.8 color=grey) ;
run;

 

Ksharp_0-1744079251544.png

 

 

2)And if your dataset has been sorted as you did, you can code it as simple as this:

 

data have;
input code region &$20. growth_rate year;
datalines;
0 North America  -5.92 2020
0 North America  -2.18 2021
0 North America  -7.47 2022
0 North America  -2.17 2023
0 North America  -9.64 2024
1 South America  0.36 2020
1 South America  2.69 2021
1 South America  -8.13 2022
1 South America  1.22 2023
1 South America  -1.34 2024
2 Asia  -1.53 2020
2 Asia  2.18 2021
2 Asia  5.64 2022
2 Asia  6.80 2023
2 Asia  8.70 2024
3 Europe  -9.68 2020
3 Europe  3.91 2021
3 Europe  5.48 2022
3 Europe  3.52 2023
3 Europe  3.69 2024
4 Africa  3.29 2020
4 Africa  7.97 2021
4 Africa  2.48 2022
4 Africa  7.36 2023
4 Africa  1.31 2024
5 Oceania  8.00 2020
5 Oceania  -6.05 2021
5 Oceania  6.91 2022
5 Oceania  -1.09 2023
5 Oceania  -7.46 2024
;
run;

 

proc sort data=have(where=(year=2024)) out=temp;
by descending growth_rate ;
run;

 

data fmt;
set temp(rename=(region=start));
retain fmtname 'fmt' type 'c';
length label $ 80;
label=repeat(' ',_n_)||strip(start);
keep fmtname type start label;
run;

 

proc format cntlin=fmt;
run;

 

data have2;
set have;
_region=put(region,$fmt32.);
if region="North America" then call symput('NorthAmerica',_region);
run;

 

data have3;
set have2;
if strip(_region)="North America" then year=10*year ;
run;

%sganno
data sganno;
%SGTEXT(LABEL="North America",TEXTWEIGHT="BOLD",TEXTCOLOR="RED",TEXTSIZE=10, FILLCOLOR="white",FILLTRANSPARENCY=0,WIDTH=40,Y1SPACE="DATAVALUE",X1SPACE="LAYOUTPERCENT",YC1="&NorthAmerica.",X1=6 )
run;

 

proc sgplot data=have3 sganno=sganno  noautolegend;
title "Growth rate";
styleattrs datacolors=(
 cxf7ebde cxefdbc6 cxe1ca9e cxd6ae6b cxb4771f  cxdeebf7  cxc6dbef  cx9ecae1  cx6baed6  cx1f77b4
);
hbar _region / response=growth_rate group=year 
groupdisplay=cluster
clusterwidth=0.9
datalabel DATALABELFITPOLICY=NONE
datalabelattrs=(size=8pt)
barwidth=1 nooutline
transparency=0 dataskin=none;

xaxis display=(nolabel) min=-12 max=12;
yaxis display=(nolabel) colorbands=even colorbandsattrs=(transparency=0.8 color=grey) ;
run;

 

Ksharp_1-1744079552136.png

 

 

MFraga
Quartz | Level 8

Thank you both @DanH_sas and @Ksharp for providing solutions! I'll read more about the options DATTRMAP and RATTRMAP.

 

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

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
  • 6 replies
  • 1061 views
  • 8 likes
  • 4 in conversation
--> --> -->
OSZAR »