BookmarkSubscribeRSS Feed
Anita_n
Pyrite | Level 9

I have a question: I wrote this code to plot a graph

proc sgplot data= test dattrmap=attrmap;
where sex=“m“; 
series x=year y=amount /markers group=kind markerattrs=(symbol=circlefilled size=8) 
lineattrs=(pattern=solid thickness=2) attrid=kind;
xaxis values=(2004 to 2014 by 2) display=(nolabel);
yaxis values=(0 to 20 by 5)  label=Amount of exposure' grid;
keylegend/type=marker title= "" valueattrs=(size=8.5) noborder;
run;

I wish to use formats to change the names listed in the legend. but if I add format $test.; to the code

the attrmap doesn't work any more. Is there any way to make this possible?

 

Also I wish to make the y-values in such a way that if I have multiple plots (here using a macro) with different range of values, it automatically make the values from 0 to max by an estimated increment value (which should be determind depending on data range). How is this possible?

my regards

 

12 REPLIES 12
Jay54
Meteorite | Level 14

AttrMap works with formatted values.  So, if you use a character format for the group variable, you must put the formatted values in the attribute map.  Y axis range will automatically adjust for the data.  If you want tick values at a custom intervals, you can provide a large range in the VALUES option, but also use the VALUESHINT option.  This will keep the data range to the amount coming from the data.

Anita_n
Pyrite | Level 9

Thanks Sanjay,

but how do I give the format values in attrmap? should I add a column with format and list the corresponding formats, Or add a label

I will be glad if you go into details

Jay54
Meteorite | Level 14

It is easier if you attach your full program with sample data.

ballardw
Super User

@Anita_n wrote:

Thanks Sanjay,

but how do I give the format values in attrmap? should I add a column with format and list the corresponding formats, Or add a label

I will be glad if you go into details


You should have a variable VALUE in you attrmap data set. That value has to match the formatted value of the variable you are using.

 

If the formatted value is "ABC" then the variable value should have the value "ABC" to use the attribute map for the given attribute ID.

 

 

 

RoyPardee
Obsidian | Level 7

Heh--having just now run into this issue, a whole 6 years later, it seems to me this is undesirable behavior. It's counterintuitive, and keeps users from being able to mess with formatting w/out having to keep two different sets of values in sync.

Anybody know the process for reporting a bug? I think this merits it.

ballardw
Super User

@RoyPardee wrote:

Heh--having just now run into this issue, a whole 6 years later, it seems to me this is undesirable behavior. It's counterintuitive, and keeps users from being able to mess with formatting w/out having to keep two different sets of values in sync.

Anybody know the process for reporting a bug? I think this merits it.


Suggestion would first be to describe in a bit of detail about what is counterintuitive and undesirable.

What two "different sets of  values in sync"?

 

Discussions involving "formatted value" of SAS variables were pretty much set a very long time ago (as in last century). Most of the confusion I see is from people that do not realize/understand that Proc Format and instructions to display values differ from things like file layout, column order or other uses of the word "format".

 

And perhaps when discussing Dattrmap (Discrete meaning single values) perhaps the questions might actually relate to Rattrmap (range of values) displays?

RoyPardee
Obsidian | Level 7

sure fair enough. This code illustrates what I just went through.

data cyl_attrs ;
  retain
    id "cylinders"
    linepattern "solid"
  ;
  input
    value 2.0
    linecolor $12.
  ;
  markercolor = linecolor ;
cards;
4 green
5 pink
6 yellow
8 red
10 blue
;
run;
proc format ;
  value cyl
    4  = 'small'
    5  = 'weird'
    6  = 'large'
    8  = 'extra large'
    10 = 'ginormous'
  ;
quit ;
options orientation = landscape ;
ods graphics / height = 8in width = 10in imagemap = on ;
ods html5 path = "c:\deleteme" (URL=NONE)
         body   = "deleteme.html"
         (title = "deleteme output")
         nogfootnote
         device = svg
          ;
    proc sgplot data = sashelp.cars dattrmap = cyl_attrs ;
      loess x = weight y = horsepower / group = cylinders attrid = cylinders ;
      xaxis grid ;
      yaxis grid ;
      where 4 le cylinders le 10 ;
      * format cylinders cyl. ;
    run ;
run ;
ods html5 close ;

So, my grouping var here is a numeric. (In this dset that's an actual, ratio-level data element, but in my data it was at best ordinal. So it really didn't make sense to show the numeric values--I needed a format to make them interpretable.) I think it's counter-intuitive that the actual values I'm using to set the line & marker colors are completely different from the values I'm giving SAS to divide the points into groups.

 

Given that the grouping var is a numeric, if I want that dattrmap to work I've got to change the value type to character & perfectly match all the text strings from my format--that cyl_attrs dstep has to be:

data cyl_attrs2 ;
  retain
    id "cylinders"
    linepattern "solid"
  ;
  input
    @1  value $11.
    @13 linecolor $12.
  ;
  markercolor = linecolor ;
cards;
small       green
weird       pink
large       yellow
extra large red
ginormous   blue
;
run;

So now if I decide that 'ginormous' is unprofessional, and I want to change that format label to '2xl', I've got to remember to change the description both in the format and in the dattrmap dset. I think it'd be much cleaner if I could just set the value var to the exact type & domain as the grouping var.

Rick_SAS
SAS Super FREQ

> So now if I decide that 'ginormous' is unprofessional, and I want to change that format label to '2xl', I've got to remember to change the description both in the format and in the dattrmap dset. I think it'd be much cleaner if I could just set the value var to the exact type & domain as the grouping var.

 

Right, which is why I prefer to use the formatted values in the dattrmap and in PROC SGPLOT, rather than the unformatted values. In your example, define the format FIRST, then define the dattrmap by specifying the raw values (4,5,6,8,10) and using the PUT function to apply your format. That defines the dattrmap in terms of the formatted values. In PROC SGPLOT, apply the format to the cylinders variable.

 

For a recent example, see this thread, which also include links to blog articles:

https://communities.sas.com/t5/SAS-Programming/Bar-Chart-Axis-Parameters-and-Color-Scaling/m-p/91763...

 

You can also use programming to automatically generate the dattrmap from the data and the format

 but sometimes that is overkill. Use the simpler method when you can.

Anita_n
Pyrite | Level 9

@Jay54@ballardw: Thanks for your replies,  here are some sample data as you requested

 

the sas code:

proc format;
value $ kind
        mri_a_n= "Occ.males B"
		mri_c_n= "Death males B"
		w_n= "Occ. males L"
		y_n= "Death males L"
		mri_a_m="Occ. females B"
		mri_c_m="Death females B"
		w_m="Occ. females L"
		y_m="Death males L"
; run; proc sgplot data= test.inputdata dattrmap=test.attrmap_test; where sex="m"; format kind $kind.; series x=year y=amount /markers group=kind attrid=kind; xaxis values=(1998 to 2008 by 2) display=(nolabel); yaxis values=(0 to 50 by 5 )label='Amount of exposure' valueshint grid; keylegend/type=marker valueattrs=(size=8.5) noborder; run;

if I add the format "kind" to the code "attrmap" doesnt seem work properly any more. But if I remove the code, it works well.

But I need to apply the format to rename the variables in the legend.

 

My other question is that I need to plot about 50 or more of such graphs using a macro. The xaxis values are quiet fine. For the yaxis,  I have values which have different ranges and intervals depending on the data (but always starts from 0). eg. from 0 to 20 by 5,

from 0 to 10 by 2,  from 0 to 80 by 20, from 0 to 200 by 40, from 0 to 500 by 100 and so on...............

Is there any way to declare this in sgplot?

 

I will be very grateful for any help

Anita_n
Pyrite | Level 9

 I am still counting on any help on this post.

Jay54
Meteorite | Level 14

From your attrmap_test data set, it seems you are still using the original values in the attrmap.  Instead of "mri_a_n" the value should be the formatted value "Occ.males B" and so on.  These are the values in the legend in the graph.

 

AttrMap.pngGraph.png

Anita_n
Pyrite | Level 9

Thanks Sanjay,

I finally solved this problem just as you said, by previously appling the format in a data step to change the variables before using this in the sgplot and it worked fine. For the issue with the xaxis with different ranges and intervals. I defined this in the macro itself, this also worked perfectly. Thanks

 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 12 replies
  • 2182 views
  • 5 likes
  • 5 in conversation