user601828
user601828

Reputation: 509

sas if then else statement

I have this code below, I need it to set elig_factor[2] to 1 when status is =1 and hudadmin is in 1 or 2 or 3 else set elgi_factor[2] =0. But it sets elig_factor[2] = 0 anyway. Can someone please help?

if ("&r_start" eq 1) then 
 do;
 if ( 2011<=built <= 2014) then elig_factor[1] = '1';
 else elig_factor[1] = '0';

 if (status eq '1' and hudadmin eq '1') then elig_factor[2] = '1';
    else elig_factor[2] = '0';
  if (status eq '1' and hudadmin eq '2') then elig_factor[2] = '1';
    else elig_factor[2] = '0';
  if (status eq '1' and hudadmin eq '3') then elig_factor[2] = '1';
    else elig_factor[2] = '0';


 if (np_all gt 0) then elig_factor[3] = '1';
   else elig_factor[3] = '0';
 if (np_black gt 0) then elig_factor[4] = '1';
   else elig_factor[4] = '0';
 if (np_age65 gt 0) then elig_factor[5] = '1';
   else elig_factor[5] = '0';
 if (np_hisp gt 0) then elig_factor[6] = '1';
   else elig_factor[6] = '0';

 elig_factor[7] = occ;
 elig_factor[8] =vac;
    end;

Upvotes: 1

Views: 159

Answers (2)

Joe
Joe

Reputation: 63424

This is actually even easier if you use the boolean results. The only difference below is that it returns numeric results - if you must have '1' then put each of these to a character or wrap each of them in cats.

 if ("&r_start" eq 1) then 
 do;
   elig_factor[1] = ( 2011<=built <= 2014) ;
   elig_factor[2] = (status eq '1' and hudadmin in ('1','2','3'));
   elig_factor[3] = (np_all gt 0) ;
   elig_factor[4] = (np_black gt 0);
   elig_factor[5] = (np_age65 gt 0);
   elig_factor[6] = (np_hisp gt 0);
   elig_factor[7] = occ;
   elig_factor[8] = vac;
 end;

Upvotes: 1

mjsqu
mjsqu

Reputation: 5417

You almost answered the question yourself when you said:

when status is =1 and hudadmin is in 1 or 2 or 3

I'm not sure why you haven't used the in operator here.

Anyway, to explain what your code is actually doing:

if (status eq '1' and hudadmin eq '1') then elig_factor[2] = '1';
    else elig_factor[2] = '0';

  if (status eq '1' and hudadmin eq '2') then elig_factor[2] = '1';
    else elig_factor[2] = '0';

  if (status eq '1' and hudadmin eq '3') then elig_factor[2] = '1';
    else elig_factor[2] = '0';

Each if statement is evaluated in turn, ignoring the results of the past if statements. So, if you have a situation where hudadmin = 1 then the first if statement is triggered, setting elig_factor[2] to '1', the subsequent else is ignored.

When the second if statement is reached, it is checked and found to be FALSE, so the else statement is run, setting elig_factor[2] to '0', despite having previously set it to '1'.

So you have two options:

Amend your code so it does what you want

if (status eq '1' and hudadmin eq '1') then elig_factor[2] = '1';
else if (status eq '1' and hudadmin eq '2') then elig_factor[2] = '1';
else if (status eq '1' and hudadmin eq '3') then elig_factor[2] = '1';
else elig_factor[2] = '0';

This checks if hudadmin = '1', if not then it checks if hudadmin='2', if not then '3', only once it has checked hudadmin is not '1','2' or '3' then it will set elig_factor[2] = '0'.

The code is sound, but a little over engineered, I would go with the following approach

Use the in operator

if (status eq '1' and hudadmin in ('1','2','3')) then elig_factor[2] = '1';
else elig_factor[2] = '0';

This checks the condition in one statement, is easier to read, and is arguably more efficient.

Upvotes: 2

Related Questions