2

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.

jilles de wit
  • 7,060
  • 3
  • 26
  • 50
  • 1
    [This earlier question](http://stackoverflow.com/questions/28328688/can-i-promote-notes-about-uninitialized-variables-to-errors), while not exactly a duplicate of yours, got a a great general answer that might be what you're looking for. – Jeff Jul 20 '15 at 16:26
  • 1
    This isn't an exact answer to your question, but have you seen [this post](http://stackoverflow.com/questions/28328688/can-i-promote-notes-about-uninitialized-variables-to-errors)? 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 Jul 20 '15 at 16:28
  • 1
    @Jeff Good timing... – Joe Jul 20 '15 at 16:28
  • @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 Jul 21 '15 at 09:22

1 Answers1

1

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;
Shenglin Chen
  • 4,504
  • 11
  • 11
  • 1
    It seems to me the OP wants a solution to this that isn't dependent on the individual calculation - rather based on the status of the data step notes/warnings entirely. – Joe Jul 20 '15 at 16:23
  • Yes, there are hundreds of variables that change value (and are looped over) in several layers of macros. Checking them all each step is a possibility, but not a very easy one. – jilles de wit Jul 21 '15 at 09:19