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

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.

1 ACCEPTED SOLUTION

Accepted Solutions
DanH_sas
SAS Super FREQ

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

View solution in original post

3 REPLIES 3
PeterClemmensen
Tourmaline | Level 20

Can you provide some example data representing your actual data? That way, we can help you the best and provide a usable code answer 🙂

DanH_sas
SAS Super FREQ

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

ballardw
Super User

@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;

SAS Innovate 2025: Call for Content

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!

Submit your idea!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 15509 views
  • 4 likes
  • 4 in conversation