Hello,
I need to graph the mean and SE of the variable COST for 2 groups of people (Age_group="Younger", "Older") in one plot. The plot is basically graphing the trend of cost over time. The two groups of people need to be next to each other so that their SE do not overlap and I need a line connecting each point for both groups. I know my code has to look something like what I listed below.
What can I add to the code below so that the mean & SE for the two groups will appear next to one-another for each year, and how can I customize the marker color and lineattrs for each group?
Title "Average cost per year";
proc sgplot data=final;
scatter x=year y=cost/ yerrorlower=lowercost
yerrorupper=uppercost
markerattrs=(color=black symbol=SquareFilled)errorbarattrs=(color=black);
series x=year y=cost/group= age_group lineattrs=(color=blue pattern=2);
XAXIS label="Year" VALUES= (2001 TO 2007 BY 1);
YAXIS label="Average Cost" VALUES= (0 TO 50 BY 10);
run;
I appreciate any help you can offer.
It appears that you have pre-computed your values so that you can use them with a SERIES plot. For the record, what you request can also be done using VLINE statement using the raw data (with actually less code).
Here are a few things you'll want to do:
1. Set the XAXIS to be DISCRETE:
XAXIS label="Year" type=Discrete;
2. Set the GROUP variable on the SCATTER statement, and use GROUPDISPLAY=CLUSTER on both statements.
3. Remove the BLACK colors from MARKERATTRS and ERRORBARATTRS so that you can control the color by group values (just remove the ERRORBARATTRS option altogether). Also, remove the BLUE color from the LINEATTRS on the SERIES statement.
As for controlling the group colors, you have two options. If you only care about the colors used, but not how they are assigned, the simplest way is to use the STYLEATTRS statement in SGPLOT. In your case, you'll want to use the DATACONTRASTCOLOR option. For example:
STYLEATTRS datacontrastcolors=(purple orange);
If you also want to control how they are assigned, you can use a Discrete Attributes Map instead. This lets you associate visual attributes to a particular group value.
Summing up, the code below reflects the comments above, using STYLEATTRS:
Title "Average cost per year";
proc sgplot data=final;
styleattrs datacontrastcolors=(purple orange);
scatter x=year y=cost/ yerrorlower=lowercost
yerrorupper=uppercost group=age_group groupdisplay=cluster
markerattrs=(symbol=SquareFilled);
series x=year y=cost/group= age_group groupdisplay=cluster
lineattrs=(pattern=2);
XAXIS type=discrete label="Year";
YAXIS label="Average Cost" VALUES= (0 TO 50 BY 10);
run;
An attrmap example would look something like the following:
data attrmap;
retain id "myid";
input value $ linecolor $ markercolor $;
cards;
Younger purple purple
Older orange orange
;
run;
Title "Average cost per year";
proc sgplot data=final dattrmap=attrmap;
scatter x=year y=cost/ yerrorlower=lowercost
yerrorupper=uppercost group=age_group groupdisplay=cluster
markerattrs=(symbol=SquareFilled) attrid=myid;
series x=year y=cost/group= age_group groupdisplay=cluster
lineattrs=(pattern=2) attrid=myid;
XAXIS type=discrete label="Year";
YAXIS label="Average Cost" VALUES= (0 TO 50 BY 10);
run;
Hope this helps!
Dan
Can you provide some example data representing your actual data? That way, we can help you the best and provide a usable code answer 🙂
It appears that you have pre-computed your values so that you can use them with a SERIES plot. For the record, what you request can also be done using VLINE statement using the raw data (with actually less code).
Here are a few things you'll want to do:
1. Set the XAXIS to be DISCRETE:
XAXIS label="Year" type=Discrete;
2. Set the GROUP variable on the SCATTER statement, and use GROUPDISPLAY=CLUSTER on both statements.
3. Remove the BLACK colors from MARKERATTRS and ERRORBARATTRS so that you can control the color by group values (just remove the ERRORBARATTRS option altogether). Also, remove the BLUE color from the LINEATTRS on the SERIES statement.
As for controlling the group colors, you have two options. If you only care about the colors used, but not how they are assigned, the simplest way is to use the STYLEATTRS statement in SGPLOT. In your case, you'll want to use the DATACONTRASTCOLOR option. For example:
STYLEATTRS datacontrastcolors=(purple orange);
If you also want to control how they are assigned, you can use a Discrete Attributes Map instead. This lets you associate visual attributes to a particular group value.
Summing up, the code below reflects the comments above, using STYLEATTRS:
Title "Average cost per year";
proc sgplot data=final;
styleattrs datacontrastcolors=(purple orange);
scatter x=year y=cost/ yerrorlower=lowercost
yerrorupper=uppercost group=age_group groupdisplay=cluster
markerattrs=(symbol=SquareFilled);
series x=year y=cost/group= age_group groupdisplay=cluster
lineattrs=(pattern=2);
XAXIS type=discrete label="Year";
YAXIS label="Average Cost" VALUES= (0 TO 50 BY 10);
run;
An attrmap example would look something like the following:
data attrmap;
retain id "myid";
input value $ linecolor $ markercolor $;
cards;
Younger purple purple
Older orange orange
;
run;
Title "Average cost per year";
proc sgplot data=final dattrmap=attrmap;
scatter x=year y=cost/ yerrorlower=lowercost
yerrorupper=uppercost group=age_group groupdisplay=cluster
markerattrs=(symbol=SquareFilled) attrid=myid;
series x=year y=cost/group= age_group groupdisplay=cluster
lineattrs=(pattern=2) attrid=myid;
XAXIS type=discrete label="Year";
YAXIS label="Average Cost" VALUES= (0 TO 50 BY 10);
run;
Hope this helps!
Dan
@lousam wrote:
Hello,
I need to graph the mean and SE of the variable COST for 2 groups of people (Age_group="Younger", "Older") in one plot. The plot is basically graphing the trend of cost over time. The two groups of people need to be next to each other so that their SE do not overlap and I need a line connecting each point for both groups. I know my code has to look something like what I listed below.
What can I add to the code below so that the mean & SE for the two groups will appear next to one-another for each year, and how can I customize the marker color and lineattrs for each group?
Title "Average cost per year";
proc sgplot data=final;
scatter x=year y=cost/ yerrorlower=lowercost
yerrorupper=uppercost
markerattrs=(color=black symbol=SquareFilled)errorbarattrs=(color=black);
series x=year y=cost/group= age_group lineattrs=(color=blue pattern=2);
XAXIS label="Year" VALUES= (2001 TO 2007 BY 1);
YAXIS label="Average Cost" VALUES= (0 TO 50 BY 10);
run;
I appreciate any help you can offer.
The STYLEATTRS statement can be used to set attributes or a DATTRMAP set can be used to associate specific Group values with a consistent set of line, marker and text attributes.
I'm not sure what you mean by "mean & SE for the two groups will appear next to one-another ". Perhaps you may be thinking of an XAXISTABLE to show the text values associated with the shown markers. That would be one way to show below the axis rows of values aligned with the axis ticks.
From the documentation here is a brief example of XAXISTABLE showing two tables and using a data set you should have available.
proc sgplot data=sashelp.class (where=(age < 13)); scatter x=name y=height; xaxistable age / class=age title="Student Age" location=inside valueattrs=(color=red) labelattrs=(color=red) titleattrs=(color=red); xaxistable weight height / valueattrs=(color=blue); run;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.