Google SAS Search

Add to Google

Thursday, December 01, 2005

Goto Memories

December already?! Seems like only yesterday I was dressing my little baby up for her first Halloween. And now we've already entered the *most wonderful time of the year*. A lot of people complain about the stores setting up their Christmas displays too early. Me? I like it. Bring on the displays! I like Christmas. I like winter. I like the holidays. I just wish I could get over this head cold. You know when you get a cold and it seems like your nose will never return to normal? Like you can't even remember what it was like to not have a cough? I hate having a cold.

When I was a kid my brother and I saved all our money one summer and bought ourselves a Commodore 64. That was the best Christmas ever. I would stay up all night programming in BASIC to get a smiley face sprite to bounce around the screen. I had to save my programs to cassette tape because we hadn't bought a disk drive yet. They were really expensive back then. I wish I had one of those cassette tapes now. If you played it back in the stereo it would make this weird analog warbly noise. I'd love to see what my BASIC code looked like. It'd probably be incomprehensible to me now. I remember I used to like cramming as many statements as possible onto one line and I think I used a lot of GOTO statements. Terrible, terrible bad habits for a 10 year old to be picking up!

So where am I going with this? This is a SAS blog after all, not a commodore blog. I was supposed to share some nugget of wisdom about programming in SAS but instead started rambling about BASIC and GOTO statements. Must be the cough syrup.

I still use GOTO statements today. Do you? They can come in quite handy for SAS/MACRO. Consider the following code. I know it's not a new technique, but it's useful and worth sharing.


* just two little data sets to work with;
data base;
input key;
datalines;
1
2
3
4
;

data newRecords;
input key;
datalines;
1
2
;

*************************************;

%macro earlyTermination();

%* Suppose you wanted to merge some data and see if
there were any records that didnt match. Then you
want to do some processing on those non-matching records.
Otherwise if there were no non-matches you dont want
to do any more processing.;

proc sort data = base;
by key;
run;

proc sort data = newRecords;
by key;
run;

data nonMatches;
merge base(in=base)
newRecords(in=newRecords);
by key;
if newRecords and not base then output;
run;

%* check to see if there are any records in nonMatches;
%let dsid = %sysfunc( open( nonMatches ) );
%let nobs = %sysfunc( attrn( &DSID, nobs ) );
%let rc = %sysfunc( close( &DSID ) );

%if &NOBS = 0 %then %goto done;

%* otherwise do some processing with the
nonMatches
.
.
.;

%put There were &NOBS non-matching records;

%done:
%mend earlyTermination;

%earlyTermination;


In this case we goto an empty label. But there could have been some statements after %DONE. It's important to note however, that the %DONE label will be executed NO MATTER WHAT.

Happy programming.

1 comment:

  1. Hi Stephen!

    The example illustrates the need for GOTO in SAS Macro programming. Remember in version 9: The
    %return statement:

    %macro test(data=);
    %if &data= %then %do;
    %put ERROR: Need a dataset!;
    %return;
    %end;
    proc print data=&data;
    run;
    %mend;

    I guess you already knew! :-)

    Regards,
    Peter Kellberg,
    Statistics Denmark

    ReplyDelete