BookmarkSubscribeRSS Feed
numbergirl
Obsidian | Level 7

Hi,
Thanks in advance for responses.

I'm using SAS 9.4 and outputting to an RTF file.  How do I format the group names in the legend, or allow character values for the group variable, without losing the plot attributes?   The plot below is the current output, which is correct except for the legend values "1,2,3."    See comments in all caps in code below.  

** DATASET MYDATA HAS STRATVAR= "lab >= 40", "lab <40", and "total";
 *  I WOULD LIKE THE LEGEND OF THE PLOT TO SHOW THOSE CHARACTER STRINGS.;
 * HOWEVER WHEN I USE A CHARACTER VARIABLE FOR STRATVAR (INSTEAD OF NUMERIC), THE ATTRIBUTE MAP DOESNT GET USED.;
 * AND IF I USE A NUMERIC VARIABLE AND ASSISGN A FORMAT, WHETHER THE FORMAT STATEMENT IS USED IN THE DATA STEP OR;
 *      IN THE PROC SGPLOT PROCEDURE, THE ATTRIBUTGE MAP DOESNT GET USED.;


*  NOTE:  THE LINECOLORS BELOW ARE RED, BLUE, AND YELLOW;
data myattrmap0;
length color $ 9;
input ID $ value linecolor $ linethickness ;  ** can also use linecolor, linethickness, symbolcolor? symbolthicknes?;
datalines;
myid  1 CXB2182B 3 
myid  2 CX2A25D9 3 
myid  3 CXD17800 3 
;
run;
data myattrmap;
  set myattrmap0;
  markercolor=linecolor;
run;

options formchar="|____|+|___+=|_/\<>*" pageno=1 nonumber nodate orientation=landscape center ;
ods listing close;
ods rtf file="outputpath\myfile.rtf" nogtitle nogfootnote;

ods graphics / reset  width=9in height=5.5in;
ods graphics on;

title3 "Survival, Kaplan-Meier Estimates";

ods select none;
proc lifetest data=mydata plots=survival(atrisk=0 to 30 by 5);
   time time*event(0);
   strata stratvar;
   ods output Survivalplot=SurvivalPlotData;
   run;
ods select all;


proc sgplot data=SurvivalPlotData dattrmap=myattrmap;
  step x=time y=survival / group=stratum lineattrs=(pattern=solid) name='s' attrid=myid;
  scatter x=time y=censored / markerattrs=(symbol=plus size=10) name='c';
  scatter x=time y=censored / markerattrs=(symbol=plus size=10) GROUP=stratum attrid=myid;
  keylegend 'c' / location=inside position=topright;
  keylegend 's';
  xaxis label='Months';
  yaxis min=0;
run;

ods rtf close;
ods listing;

 

survivalplot.PNG

 

9 REPLIES 9
DanH_sas
SAS Super FREQ

1. Define a format to turn the "1,2,3" into the strings you want.

2. Associate that format to the STRATUM variable. You can do that in the SGPLOT procedure by adding this line:

    format stratum mystratum.; /* or whatever you call the format */

3. Instead of using "1, 2, 3" as the values in the attrmap, use the FORMATTED values. By default, these value are case-sensitive, so keep that in mind (there is an option to make them insensitive, depending on your version of SAS).

 

This should give you what you want.

 

Hope this helps!

Dan

numbergirl
Obsidian | Level 7

Hi Dan,
Thanks for your reply.    The attribute map is lost when using a format statement.   Tried it as you said.   If you find a way that works, I would like to know.   What I've done instead for now is define the groups as "1: Total", 2: xxx", "3: xxx" directly instead of using a format.  

 

It works, but it's more confusing to look at (than simply "total", "xxx", "xxx") because the order of the lines on the plot doesn't match the numbered order in the legend.

Helena 

DanH_sas
SAS Super FREQ

Here is a simple example I made to demonstrate what I was describing:

 

proc format;
value mygroups 1="group 1"
               2="group 2"
               3="group 3"
;
run;

data test;
do grp=1 to 3;
  do x=1 to 5;
     y = ranuni(123) * 100;
     output;
  end;
end;
run;

data attrmap_num;
retain id "myid";
input value $ fillcolor $;
cards;
1 purple
2 yellow
3 orange
;
run;

data attrmap_format;
retain id "myid";
input value $ 1-7 fillcolor $;
cards;
group 1 purple
group 2 yellow
group 3 orange
;
run;

/* Raw group */
Title "Raw Group";
proc sgplot data=test dattrmap=attrmap_num;
vbar x / response=y group=grp attrid=myid;
run;

/* Formatted group */
Title "Formatted Group";
proc sgplot data=test dattrmap=attrmap_format;
format grp mygroups.;
vbar x / response=y group=grp attrid=myid;
run;
numbergirl
Obsidian | Level 7

Hi Dan and BallardW,
Thanks, Dan, for the coding example! I'll hang on to those.  There's still a problem with survival plots.   I applied Dan's solution. Code and results follow.   The graph goes back to default colors and line thickness instead of using attribute map attributes as shown in the plot (notice plot in my original message uses yellow, not green.

 

Since Dan's code works for the bar charts, I wonder if being in a macro or using output from the LIFETEST procedure is causing the problem.

  *** formats ** ;
proc format;
  value groupfmt 1='Total'
                        2='group a'
			3='group b';
run;

  *** attribute map;
data myattrmap0;
length linecolor $ 9 ;
input ID $ value $ 7-18 linecolor $ linethickness ; 
datalines;
myid  1: Total     CXB2182B 3 
myid  2: PSA >= 50 CX2A25D9 3 
myid  3: PSA < 50  CXD17800 3 
;
run;

data myattrmap;
  set myattrmap0;
  markercolor=linecolor;
run;

***************************;
*  Survival Plots         *;
***************************;
  * by  group;


%macro plt_bygp (dat=, time=, event=, wher=%str(1=1), strat=, ttl1=);
options formchar="|____|+|___+=|_/\<>*" pageno=1 nonumber nodate orientation=landscape center ;
ods listing close;
ods rtf file="mypath\myfile.rtf" /*style=endocyte*/ startpage=no nogtitle nogfootnote;

ods graphics width=9in height=5.5in;
ods graphics on;

ods rtf startpage=now;
title3 "&ttl1., Kaplan-Meier Estimates";

ods select none;
proc lifetest data=mydata(where=(&wher)) plots=survival(atrisk=0 to 30 by 5);
   time &time.*&event.(0);
   strata &strat.;
   ods output Survivalplot=SurvivalPlotData;
   run;
ods select all;



proc sgplot data=SurvivalPlotData dattrmap=myattrmap;
  step x=time y=survival / group=stratumnum lineattrs=(pattern=solid) name='s' attrid=myid;
  scatter x=time y=censored / markerattrs=(symbol=plus size=10) name='c';
  scatter x=time y=censored / markerattrs=(symbol=plus size=10) GROUP=stratumnum attrid=myid;
  keylegend 'c' / location=inside position=topright;
  keylegend 's';
  xaxis label='Months';
  yaxis min=0;
  format stratumnum groupfmt.;
run;

ods rtf close;
ods listing;

%mend plt_bygp;


%plt_bygp (ttl1=%str(Overall Survival), dat=mydata, time=tt_death_mo, event=deceased, strat=survgroup );

Survplot2 for sas.PNG

DanH_sas
SAS Super FREQ

In your program you called your attrmap. "myattrmap0":

data myattrmap0;

 

But you referred to it as "myattrmap" in SGPLOT:

 

proc sgplot data=SurvivalPlotData dattrmap=myattrmap;

 

Since the attrmap could not be found, it fell back to default colors. 

numbergirl
Obsidian | Level 7

Actually, the data step right below it is 

Data myattribmap;

 

It's something else.    The attribute map works if I take the format statement out, as shown in my first post.

Helena

 

DanH_sas
SAS Super FREQ

The FORMAT value strings do not match the VALUE column in your attrmap:

 

proc format;
  value groupfmt 1='Total'
                        2='group a'
			3='group b';
run;

  *** attribute map;
data myattrmap0;
length linecolor $ 9 ;
input ID $ value $ 7-18 linecolor $ linethickness ; 
datalines;
myid  1: Total     CXB2182B 3 
myid  2: PSA >= 50 CX2A25D9 3 
myid  3: PSA < 50  CXD17800 3 
;
run;

Therefore, the lookup will fail; and the colors will go back to the default.

numbergirl
Obsidian | Level 7

the text matches the format in my code i used for work-- i had cut and pasted to make sure.   when i edited to post here, i inadvertently forgot to edit the attribute map.  that's not the problem.  

 

i've gotten the suggestion sent to work for a bar chart that wasn't in a macro, so perhaps the macro is the problem??  i don't know because after trying so many combinations of things, i switched over to posting on SAS communities.   

Helena

ballardw
Super User

@numbergirl wrote:

Hi Dan,
Thanks for your reply.    The attribute map is lost when using a format statement.   Tried it as you said.   If you find a way that works, I would like to know.   What I've done instead for now is define the groups as "1: Total", 2: xxx", "3: xxx" directly instead of using a format.  

 

It works, but it's more confusing to look at (than simply "total", "xxx", "xxx") because the order of the lines on the plot doesn't match the numbered order in the legend.

Helena 


Explain what you mean by "The attribute map is lost when using a format statement".

If you change the formatted values with out changing the attribute map to match then the attribute map can not be applied as the requirement is for the value in the attribute map to match the formatted value of the group variable. So if you changed the format and didn't modify the map, the map cannot be used.

 

Without seeing the exact values you are using it is hard to recommend specific Keylegend options that might affect the appearance such as SORTORDER.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

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
  • 9 replies
  • 2245 views
  • 1 like
  • 3 in conversation