I need to make the graph like this.
I made everything except these "U.S. native" and "All immigrants" lines color different from others.
PROC FORMAT cntlout=library.fcpjan2016;
value educ 3= "Less than high school"
2= "High school graduate and some college"
1= "Bachelor's degree";
* calculate total;
data total;
set library.jan2016pub;
if penatvty = -1 then delete;
if peeduca = -1 then delete;
penatvty = 0;
if 31 <= peeduca <=38 then educ = 3;
else if 39 <= peeduca <= 42 then educ = 2;
else if 43 <= peeduca <=46 then educ = 1;
keep penatvty educ;
run;
* calculate US native;
data us;
set library.jan2016pub;
if penatvty = -1 then delete;
if peeduca = -1 then delete;
if penatvty in (57,60,66,69,73,78);
if 31 <= peeduca <=38 then educ = 3;
else if 39 <= peeduca <= 42 then educ = 2;
else if 43 <= peeduca <=46 then educ = 1;
penatvty = 1;
keep penatvty educ;
run;
* calculate only immigrant data;
data immigrant;
set library.jan2016pub;
if penatvty = -1 then delete;
if peeduca = -1 then delete;
if penatvty in (57,60,66,69,73,78) then delete;
if 31 <= peeduca <=38 then educ = 3;
else if 39 <= peeduca <= 42 then educ = 2;
else if 43 <= peeduca <=46 then educ = 1;
keep penatvty educ;
* combine all;
data immigrant;
set immigrant total us;
year = "Jan 2016";
label educ = "education level";
run;
* select the cases with only top 10 countries sending immigrant to the US;
proc freq data= immigrant;
tables penatvty /out = percent0;
run;
proc sort data=percent0;
by decending count;
run;
data select1;
set percent0;
if _n_ < 51;
keep penatvty;
run;
* add the education variable to the selected countries;
proc sort data=select1; by penatvty; run;
proc sort data=immigrant; by penatvty; run;
data immigrant2;
merge select1(in=x) immigrant;
if x;
by penatvty;
run;
* sort by descedning order by education;
proc sort data=immigrant2;
by year penatvty;
run;
proc freq data=immigrant2 noprint;
by year penatvty ;
tables educ / out=percent outpct;
run;
proc sort; by educ descending percent ;
data percent;
set percent;
if 0 < = penatvty <= 1 then educx = educ;
run;
* create annotations;
%sganno;
data anno;
%sgtext
(label="Bachelor's degree", x1=40,y1=92,
width=22, widthunit="percent", textsize=11,
textcolor="white",x1space='graphpercent', TEXTWEIGHT= "BOLD",
y1space='graphpercent', transparency=0.2,
anchor='topleft' );
%sgtext
(label="High school graduae and some college", x1=55,y1=50,
width=22, widthunit="percent", textsize=11, TEXTWEIGHT= "BOLD",
textcolor="GraphData1:contrastColor",x1space='graphpercent',
y1space='graphpercent', transparency=0.2,
anchor='topleft' );
%sgtext
(label="Less than high school", x1=72,y1=26,
width=22, widthunit="percent", textsize=11,
textcolor="white",x1space='graphpercent', TEXTWEIGHT= "BOLD",
y1space='graphpercent', transparency=0.2,
anchor='topleft' );
run;
proc sgpanel data=percent pctlevel=group sganno=anno;
styleattrs datacolors=(black gold teal);
panelby year / columns=1;
hbar penatvty/ group=educ response=percent grouporder=ascending;
hbar penatvty/ group=educx response=percent grouporder=ascending transparency=0.9;;
rowaxis FITPOLICY=NONE discreteorder=data;
format penatvty penatvty. educ educ. ;
keylegend / sortorder=ascending;
run;
I got error
ERROR: The same group variable must be used for summarized plots.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SGPANEL used (Total process time):
real time 0.01 seconds
cpu time 0.00 seconds
The error message is saying that you cannot use two different GROUP variables when overlaying VBAR statements. If your values are already summarized, use VBARPARM. Or, you can use VBARBASIC.
Thank you for your reply. It kind of worked but didn't work for my purpose. I cannot change the color of 2 bars. where did I do wrong?
proc sgpanel data=percent pctlevel=group sganno=anno;
*styleattrs datacolors=(black gold teal);
panelby year / columns=1;
HBARPARM category = penatvty response=percent /group =educ grouporder=ascending FILLATTRS= (COLOR= "black gold teal");
HBARPARM category = penatvty response=percent / group=educx grouporder=ascending FILLATTRS= (COLOR= "gray yellow green")transparency=1.0;
rowaxis FITPOLICY=NONE discreteorder=data;
format penatvty penatvty. educ educ. ;
keylegend / sortorder=ascending;
run;
You have grouped bar charts. I assume the segments are groups. Then, those colors will come from the group colors you have set in the styleattrs (black, gold and teal). If you set the fill color to some other color like BLACK, all the segments will become black. Also, you cannot set the color as you have done (FILLATTRS= (COLOR= "black gold teal")). Please refer to the documentation on how to set colors.
If you have stacked groups in each bar, one HBARPARM statement should be enough with all the segments you need. The second HBARPARM will only overlay right over the first, unless you offset them.
thank you for your reply. It getting closer but not quite.
Why I got this error message and not be able to use attribute?
5321 data attrmap;
5322 length value $ 9 fillcolor $ 9;
5323 retain linecolor "black";
5324 input id $ value $ fillcolor $;
5325 datalines;
NOTE: The data set WORK.ATTRMAP has 6 observations and 4 variables.
NOTE: DATA statement used (Total process time):
real time 0.03 seconds
cpu time 0.00 seconds
5332 ;
5333
5334 run;
5335 proc sgpanel data=percent pctlevel=group dattrmap=attrmap sganno=anno;
5336
5337 panelby year / columns=1;
5338
5339 HBARPARM category = penatvty response=percent /group=educ grouporder=ascending
5340 attrid=percent;
5341 HBARPARM category = penatvty response=percent1 /group=educ grouporder=ascending
5342 attrid =percent1;
5343 rowaxis FITPOLICY=NONE discreteorder=data;
5344 format penatvty penatvty. educ educ. ;
5345 keylegend / sortorder=ascending;
5346 run;
WARNING: Only one attrid can be assigned to the "EDUC" variable. The additional attrid will be
ignored.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.