2
votes

Is there a way to detect that operations were performed on missing values during a SAS datastep? I've looked at all the automatic macro variables but none seem to do what I need. I don't think I can set the strictness of SAS code checking so that the NOTE: Missing values were generated... message becomes an error (which would presumably give &syscc some value).

Sample code:

data _null_;
foo=1;
bar=2;
baz=foo*bar;
put foo= bar= baz= "syscc=&syscc syserr=&syserr";
foo=.;
bar=2;
baz=foo*bar;  /*<-- at this point the note about missing values is generated */
/* Here I'd like to be able to do something like; */
/* if [SOME CONDITION] then do;
/*   put "operation on missing values occured!" _ALL_;
/*   [DO SOMETHING];
/* end; */
put foo= bar= baz= "syscc=&syscc syserr=&syserr";
foo=2;
bar=3;
baz=foo*bar;
put foo= bar= baz= "syscc=&syscc syserr=&syserr";
run;

Log output (without the source):

FOO=1 BAR=2 BAZ=2 syscc=0 syserr=0
FOO=. BAR=2 BAZ=. syscc=0 syserr=0
FOO=2 BAR=3 BAZ=6 syscc=0 syserr=0
NOTE: Missing values were generated as a result of performing an operation on missing values.
      Each place is given by: (Number of times) at (Line):(Column).
      1 at 8:8
NOTE: DATA statement used (Total process time):

Log output I'd like to see:

FOO=1 BAR=2 BAZ=2 syscc=0 syserr=0
operation on missing values occured! FOO=. BAR=2 BAZ=. _ERROR_=0 _N_=1
FOO=. BAR=2 BAZ=. syscc=0 syserr=0
FOO=2 BAR=3 BAZ=6 syscc=0 syserr=0
NOTE: Missing values were generated as a result of performing an operation on missing values.
      Each place is given by: (Number of times) at (Line):(Column).
      1 at 8:8
NOTE: DATA statement used (Total process time):

The reason I'm looking for this (rather than just checking the values of individual variables) is that I get very few notes about missing values from one datastep that continuously collects data through a socket (maybe one in 10000 lines read from the socket triggers the missing values note) and within the datastep there are a few hundred numerical variables hidden deep within three layers of macro's, and I'm trying to debug this.

[edit] The note2err dsoption suggested by Jeff and Joe does something, but it is a bit too harsh. It just stops execution instantly at the point the missing value message is generated without any more helpfull comments in the log. Now the log is:

FOO=1 BAR=2 BAZ=2 syscc=0 syserr=0
ERROR: Operation performed on missing value at line 8 column 9.
ERROR: Termination due to Missing Value
NOTE: The SAS System stopped processing this step because of errors.
NOTE: DATA statement used (Total process time):

This is not really helpfull (though it greatly increases the need to fix the issue if I leave it enabled). Setting option noerrorabend doesn't change this behaviour.

1
This earlier question, while not exactly a duplicate of yours, got a a great general answer that might be what you're looking for. - Jeff
This isn't an exact answer to your question, but have you seen this post? The undocumented NOTE2ERR option might be helpful - at minimum, you'd find out where in the data step it happened exactly (as it would immediately error out there). - Joe
@Jeff Good timing... - Joe
@Jeff, this is exactly what I am looking for! thanks! And this also goes for Joe but I can only @ notify one person in a comment apparently... - jilles de wit

1 Answers

1
votes

If I understand your question correctly, you could try this:

data _null_;
foo=1;
bar=2;
baz=foo*bar;
put foo= bar= baz= "syscc=&syscc syserr=&syserr";
foo=.;
bar=2;
baz=foo*bar; 
if missing(foo) or missing(bar) then put "operation on missing values occured!" _all_;
else put "operation is Ok!";
put foo= bar= baz= "syscc=&syscc syserr=&syserr";
foo=2;
bar=3;
baz=foo*bar;
put foo= bar= baz= "syscc=&syscc syserr=&syserr";
run;