Creating a scale using an annotate dataset

Introduction

What I am going to show you on this page is one way to create a time scale using an annotate dataset.

annotate macros

If you are aware of annotate datasets then you might or might not be aware of a set of macros called the "annotate macros" supplied by the SAS Institute. They are all held inside one of the autocall members named %annomac. This is unusual because normally they are single macros with the same name as the member name. You have this macro in your "core" sasmacro library if you look. The SAS Institute supply it. It isn't one of mine (for a change). These annotate macros don't save you much work, since you have to understand how annotate datasets work in their raw form to be able to use these macros - but they can make your code shorter and easier to understand. So long as using these macros suits the application you are trying to write, you will probably prefer to use them rather than use raw annotate dataset code. Of course, there is nothing to stop you mixing raw code and calls to these macros.

How to use the annotate macros has been the subject of a number of papers and I am not going to write such a paper. You can search Google for these. What I am going to show you on this page is a fairly complicated use of them when creating and using a time scale.

patient profiler time scale

What I am going to do on this page is to recreate the outline of a page created for an example graphical patient profiler. It is the first figure shown in the following document. You have to scroll down a bit
A Low Cost Graphical Patient Profiler with SAS MetaViewApplet

Note that the scale is shown from day -40 to 150 with the scale marks you can see at the bottom of the page. This is what I am going to reproduce in this document. I won't be adding any other details at this stage. That would make things too complicated. I just want you to see how I have reproduced this scale. In my code you will see how I can plot a day number to an x axis coordinate so if I wanted to I could add other details just like the patient profiler is doing. But for your sake, I will keep things simple.

The code

Note that %annomac has to be called so that the macros inside it can be complied and therefore called from inside the data step. I will be calling a few of these macros, namely %dclanno, %system, %frame, %move, %draw and %label. Don't regard my goptions as authoritative. I just keep changing them until it works for me. Feel free to change them yourself. The only complicated thing about the code below is perhaps the "drawscale" routine. This loops through the scale and calls "calcx" for each day to work out what the "x" coordinate should be. It then writes the scale value and draws a line in the graph area. If you want to play around with this code then remove "dev=html" in the goptions so that you can see the results in your output window, rather than having to look at an html file.
 
%*- The minimum and maximum days for the x axis and the scale to use -;
%let minday=-40;
%let maxday=150;
%let scale= -40/-40 | 0/D1 | 14/W2 | 28/W4 | 56/W8 | 84/W12 | 112/W16 | 150/150 ;

goptions reset=all vpos=60 hpos=120 papersize='A4' rotate=landscape
         vsize=0in hsize=0in dev=html; /* remove dev=html if you are testing */

%*- compile the annotate macros -;
%annomac(nomsg)
 

data test;
  retain minday &minday   maxday &maxday
         scale "&scale"
         xmin 30   xmax 100
         xmin2 32   xmax2 98
         ymin 3  ymax 99
         i 0
         ;
  length text $ 80 
         bit $ 30
         ;

  %dclanno
  %system(3,3)
  %frame(black,1,1)

  *- if first time through then draw the box and the scale -;
  if _n_=1 then do;
    link drawbox;
    link drawscale;
  end;

  *- put "set" statement processing after this line and before the "return" -;
  return;
 

drawbox:
  %move(xmin,ymin)
  %draw(xmax,ymin,black,1,2)
  %draw(xmax,ymax,black,1,2)
  %draw(xmin,ymax,black,1,2)
  %draw(xmin,ymin,black,1,2)
  return;

drawscale:
  y=2;
  i=1;
  bit=scan(scale,i,"|");
  do while(bit ne " ");
    day=input(scan(bit,1,"/"),6.);
    text=scan(bit,2,"/");
    link calcx;
    %label(x,2,text,black,0,0,1.2,'Times New Roman',+)
    %move(x,ymin)
    %draw(x,90,vpab,1,1)
    i=i+1;
    bit=scan(scale,i,"|");
  end;
  return;

calcx:
  *- calculate x coordinate using the day -;
  x=((day-minday)/(maxday-minday))*(xmax2-xmin2)+xmin2;
  return;

run;
 

proc ganno annotate=test;
run;
 

The output

Here is the output. Note that the layout is the same as the first figure in the document I provided a link for. To see that output then click on this link.

Conclusion

This document shows you one way to create a time scale using an annotate dataset, with particular emphasis given to the "annotate macros" to achieve this.
 


 
 

Go back to the home page.

E-mail the macro and web site author.