of the Month
Sometimes when a dataset is printed no observations are present. By default, SAS will not print the dataset but on occasions the requirement is to print out a message with the fact that there are no observations.
First, lets but together a macro that reports the number of observations in a dataset:
%macro numobs(dsn); %global num; data _null_; if 0 then set &dsn nobs=nobs; call symput('num',trim(left(put(nobs,8.)))); stop; run; %mend numobs;
The macro opens the dataset specified in the DSN parameter and put the number of records found in a global macro variable called NUM.
Now for some data -- this is a set of fictitious test scores for a class:
data _testscores; attrib name length=$10 score length=8; infile cards; input name $ score; cards; Jacob 54 Isabella 95 Ethan 99 Sophia 68 Michael 75 Emma 75 Jayden 65 Olivia 74 William 56 Ava 71 ; run;
For the purposes of this example, our program has to report the people who scored less than 50 in the test -- we can see in the data that there were none we have to generate the report saying that.
Lets write the code to subset the data, finding those records where the score is less than 50:
data _lt50a; set _testscores; where score<50; run;
Now lets call the macro to count the number of records:
With the number of records known to print, in this case zero, it is now time to create a dummy record with the message that "No observations meet the criteria":
%macro test; %if &num=0 %then %do; **Check if zero records found.; data _lt50a; length name $50; **Change to allow for no observation message; set _lt50a; data _noobs; length name $50; **Change to allow for no observation message; set _testscores (obs=1); **Take first observation only; call missing(of _all_); **Set all variables in the dataset to missing; name='No observations meet criteria'; **Set message in NAME variable; proc append base=_lt50a data=_noobs force; **Append to dataset that is being printed; run; %end; %mend test; %test;
First thing to note here is that this is done within a macro so that we can first conditionally test to see if the number of observations are zero, and if so, process further. The dataset _LT50a is read first, amending the size of the variable NAME to 50 characters to store the no observations message -- this is needed before we make the message. The dataset _NOOBS is generated from the ORIGINAL dataset as this assumes that there is one or more records in it, not from the _LT50A dataset as this we know has no records -- also note, only the first record is needed. The CALL MISSING statement sets all the variables in the record to missing, then in the next line we put the message to print in the listing if no observations are found. In the last step of the macro, the PROC APPEND procedure is called and the record appended.
Finally, the PROC PRINT procedure to print the report:
proc print data=_lt50a noobs label; var name score; title1 "Listing of Students With Score Less Than 50"; run;
If there are records found with a score of less tan 50 then the code in the macro TEST would not run as the macro variable NUM would not equal zero.
Hope this is useful. As always, try this code, play with it, and see what it does.
Updated June 3, 2011