Pages

SyntaxHighlighter

Tuesday, July 3, 2018

That IFN function

The IFN function returns a numeric value based whether the expression is true, false or missing. The IFC function is used to return character values in a similar fashion. Syntax for the IFN function is as follows:

IFN(logical-expression, value-returned-when-true, value-returned-when-false <, value-returned-when-missing>)

Seems pretty straight forward like a more compact IF-THEN-ELSE statement right? Let's put it to use in a simple query where the character latedate column is used to determine if something runs on a set date or everyday (ALL) as follows:

data x1;
  length latedate $8;
  do latedate = "10", "ALL";
    output;
  end;
run;

proc sql;
  create table x2 as
    select     latedate
             , mdy(7, ifn(anydigit(latedate), input(latedate, 2.), day(date())), 2018)
                as date format = date9.
    from x1 ;
quit;

While the code works, it generates two NOTEs with the keyword 'Invalid' in the SAS log that my parser finds to be in violation.


 NOTE: Invalid string.
 NOTE: Invalid argument to function INPUT. Missing values may be generated.

I found this comment in Rick Wicklin's The DO Loop blog to understand what happened. "All three arguments to the IFN function are evaluated BEFORE the function is called, and the results of the evaluation are then passed to the function."

The way I got around the Invalid NOTEs in the SAS log was to re-write the SQL query using a CASE statement as follows:

proc sql;
  create table x3 as
    select latedate
         , case 
             when anydigit(latedate) then mdy( 7, input(latedate, 2.), 2018)
             else mdy(7, day(date()), 2018)
           end as date format=date9.
    from   x1 ;
quit;

Another way to get around this issue is to use the single ? modifier on the informat to suppress the invalid data messages as follows:

proc sql;
  create table x2 as
    select     latedate
            , mdy(7, ifn(anydigit(latedate), input(latedate, ?2.), day(date())), 2018)
                as date format = date9.
    from x1 ;
quit;

The image comes from the 1998 cult classic movie "The Big Lebowski" and here is the relevant scene. With SAS there is always an IFN way to get things done. The dude abides...