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...

6 comments:

  1. In other words, a way to get around that pesky ifn() function is not to use it. I never understood why the logic of that function was not made conditional: when logical expression is true then evaluate 2nd argument; if it is false then evaluate 3rd argument.

    ReplyDelete
  2. Leonid,one usage of the IFN or IFC function when the evaluation of all 3 arguments at the same time is useful is discussed in this paper on the LAG function :
    https://www.lexjansen.com/nesug/nesug07/cc/cc33.pdf by Howard Schreier.Refer to Page 5.Of course this not the only solution to the problem being discussed in this paper.

    ReplyDelete
    Replies
    1. Thank you, Prashant, for the reference. This is a smart solution, and perhaps the only example I can think of that justifies IFN unconditional behavior. Personally, I like the solution at the top of page 4 in the paper that you reference.

      I can also refer you to my blog post Hopping for the best - calculations across SAS dataset observations which offers an alternative approach to calculations across dataset observations, be it lagging or leading.

      Delete
    2. Sure Leonid. Thanks for the Post.

      Delete
  3. This comment has been removed by a blog administrator.

    ReplyDelete
  4. Casinos Secrets and Facts | Vegas Casino Secrets
    The most カジノ シークレット popular games in Vegas casino secret are 우리카지노 slots, blackjack, and roulette. You don't 메리트카지노 need to play all these free casino games with real dealers,

    ReplyDelete