LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (January 2009, week 3)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Tue, 20 Jan 2009 16:01:06 -0500
Reply-To:     Paul Dorfman <sashole@BELLSOUTH.NET>
Sender:       "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:         Paul Dorfman <sashole@BELLSOUTH.NET>
Subject:      Re: IFN function - strange behaviour

GuyA,

It is not an either-or question. One just needs to select a tool one needs, and there is nothing specific about IFN/C that would violate this rule. You could fall prey all the same if you coded

if missing(fields) then incomplete_data2 = 1 ; else incomplete_data2 = . ;

for in this case, too, the assigned value would be overwritten by 1 or . every time the next array element is encountered, and the result of *this* IF-THEN-ELSE is no different from dataifn(missing(fields),1,.). You just need to align your programming logic with your goal.

My beef with IFN is different. I had fancied that one of big advantages of IFN would be the ability to recode, for instance,

if nmiss (a) or not b then c = . ; else c = a / b ;

as

c = IFN (nmiss (a) or not b, . , a / b) ;

The intent here is of course to avoid "Missing values were generated..." and "Division by zero detected..." notes in the log, which I intensely dislike and never, ever consider a program finished before those have been completely eradicated. The division by zero is especially vicious since it is a performance hog.

So, I had thought IFN would be at least as smart as if-then-else is to never even attempt to execute a/b if the first argument is true: it would merely assign c=., as prescribed by the second argument and that would be the end of it.

But no. IFN executes a/b regardless of how the first argument is evaluated, and of course generates a "missing" note if A and/or B is null and "division by 0" note if A is not null and B=0. In other words, the underlying code logic is equivalent to

temp = a/b ; if nmiss (a) or not b then c = . ; else c = temp ;

Which begs the question "why?". Note that it does not follow from the SAS documentation that IFN is anything but equivalent to the corresponding if- then-else and even give an example supporting the identity. Nowhere in the documentation the (significant) distinction noted above is mentioned.

I suspect that this is a semi-bug. Since in the absence of the fourth argument, the first argument can be only either true or false, there is never a reason to evaluate argument-3 expression if argument-1 is true or argument-2 expression if argument-1 is false. The reason I have halved the bug is that, after all, IFN returns a correct result, albeit doing more (essentially harmful) work than needed.

I cannot determine directly whether IFC also evaluates all 2 (or 3) result- arguments no matter what argument-1 evaluates to, for due to its character nature, it does not (thanks goodness!) produce extra junk in the log. However, it is easy to find indirectly that this is the case:

190 data _null_ ; 191 length a $ 1000 b $ 2000 d $ 3200 ; 192 a = repeat ("0123456789", 99) ; 193 b = repeat ("ABCDEFGHIJ", 199) ; 194 c = "This is a test" ; 195 do i = 1 to 1e6 ; 196 do cond = 1, 0, . ; 197 d = ifc (cond, a || b, b || c, a || c) ; 198 end ; 199 end ; 200 run ; NOTE: DATA statement used (Total process time): real time 19.46 seconds cpu time 12.87 seconds 201 202 data _null_ ; 203 length a $ 1000 b $ 2000 d $ 3200 ; 204 a = repeat ("0123456789", 99) ; 205 b = repeat ("ABCDEFGHIJ", 199) ; 206 c = "This is a test" ; 207 do i = 1 to 1e6 ; 208 do cond = 0, 1, . ; 209 if cond = 1 then d = a || b ; 210 else if cond = 0 then d = b || c ; 211 else if cond = . then d = a || c ; 212 end ; 213 end ; 214 run ; NOTE: DATA statement used (Total process time): real time 4.25 seconds cpu time 3.14 seconds

In light of the 4:1 run-time ratio, methinks evidence is pretty strong... so if one is programming not only for brevity and beauty but also for machine performance (when it matters) and/or need to avoid the nasty SAS log notes one has *programmed* to avoid, it is better to stay away from IFN/IFC... till the semi-bug is fixed.

Kind regards ------------ Paul Dorfman Jax, FL ------------

On Fri, 16 Jan 2009 01:09:42 -0800, GuyA <guya.carpenter@GMAIL.COM> wrote:

>Thanks all, that was useful. I will be more careful when using IFN and >IFC in future, and may just stick to good old IF THEN ELSE syntax!


Back to: Top of message | Previous page | Main SAS-L page