Home > database >  IF STATEMENTS LOGIC
IF STATEMENTS LOGIC

Time:10-16

This is my thought logic for my if statements in SAS. It is not running because I was told I am using it improperly. Can someone provide assistance please?

ERROR 180-322: Statement is not valid or it is used out of proper order.

data tmp_final_tab;
    merge data.final_alerts_ramts(in=a) data.final_alerts_repamts(in=b) data.final_alerts_passthru(in=c)
            data.final_alerts_wires(in=d) data.final_alerts_low_volume(in=e) data.final_alerts_bhvr(in=f);
    by clnt_no;
    if a;
        if pamt_activity_cr >= &rnd_pct_atl then atl_inda1 = 1; else atl_inda1 = 0;
        if pamt_activity_dr >= &rnd_pct_atl then atl_inda2 = 1; else atl_inda2 = 0;
    if b;
        if pamt_activity_cr >= &rnd_pct_atl then atl_indb1 = 1; else atl_indb1 = 0;
        if pamt_activity_dr >= &rnd_pct_atl then atl_indb2 = 1; else atl_indb2 = 0;
    if c;
        if (ptam/total_Amount) * 100 >= &pt_pct_atl then atl_indc = 1; else atl_indc = 0;
    if d;
        if tot_amt_wire >= &hrc_wire_amt_atl then atl_indd = 1; else atl_indd1 = 0;
        if tot_in_amt >= &wire_in_cnt_amt_atl then atl_indd2 = 1; else atl_indd2 = 0;
        if tot_out_amt >= &wire_out_cnt_amt_atl then atl_indd3 = 1; else atl indd3 = 0; 
    if e;
        if tot_amt_lv >= &lv_amt_atl then atl_ind = 1; else atl_ind = 0;
    if f;
        if tot_amt_bhvr >= &bhvr_w_hist_atl then atl_ind = 1; else atl_ind = 0;
    if a or b or c or d or e or f
        if (atl_inda   atl_indb   atl_indc   atl_indd   atl_inde   atl_indf > 0) then btl_ind = 0; else btl_ind = 1;
run;

CodePudding user response:

An if statement in SAS always has the following form (without <>):

if <boolean logic> then <code>;

If the evaluated logic needs to do more than one thing, it follows this form:

if <boolean logic> then do;
     <code>;
     <code>;
     <code>;
     ...
end;

It looks like all of your code creates binary variables. This programming shortcut in SAS will make binary 1/0 variables for you:

binary_var = (<boolean logic>);

If the logic is true, binary_var is 1. Otherwise, it is 0.

The correct form of your code is below with a cleaner form of your new binary variables.

data tmp_final_tab;
    merge data.final_alerts_ramts     (in=a) 
          data.final_alerts_repamts   (in=b) 
          data.final_alerts_passthru  (in=c)
          data.final_alerts_wires     (in=d) 
          data.final_alerts_low_volume(in=e) 
          data.final_alerts_bhvr      (in=f)
    ;

    by clnt_no;

    if a then do;
        atl_inda1 = (pamt_activity_cr >= &rnd_pct_atl);
        atl_inda2 = (pamt_activity_dr >= &rnd_pct_atl);
    end;

    if b then do;
        atl_indb1 = (pamt_activity_cr >= &rnd_pct_atl);
        atl_indb2 = (pamt_activity_dr >= &rnd_pct_atl);
    end;

    if c then atl_indc = ( (ptam/total_Amount) * 100 >= &pt_pct_atl);

    if d then do;
        atl_indd  = (tot_amt_wire >= &hrc_wire_amt_atl);
        atl_indd2 = (tot_in_amt >= &wire_in_cnt_amt_atl);
        atl_indd3 = (tot_out_amt >= &wire_out_cnt_amt_atl);
    end;

    atl_ind = ( (e AND tot_amt_lv >= &lv_amt_atl) OR (f AND tot_amt_bhvr >= &bhvr_w_hist_atl) );

    btl_ind = (sum(atl_inda, atl_indb, atl_indc, atl_indd, atl_inde, atl_indf) > 0);
run;

You technically do not even need if statements here. You can incorporate the dataset in logic into each binary variable (e.g. binary_var = (a AND <logic>);. If missing values are not needed from this operation, you can remove those if statements entirely.

CodePudding user response:

if a; is a subsetting if statement, and is very commonly used in merges like the above - although probably not what you meant. Subsetting if means that the data step should stop executing and go to the next line if the if condition is not true.

In the case of the above, if a; is true if the current merged row includes some data from the first dataset (which has in=a in its dataset options).

It doesn't make sense to sprinkle them around like you did though - that suggests you really mean if it comes from a then do these things, not if it doesn't come from a then drop it.

Also, with all six (if a; if b; if c;...) then only rows that have some value in all six input datasets would be kept - an inner join - and then your last section doesn't make sense (the one with or). But it would make more sense to do this:

if a and b and c and d and e and f;


One other note: there is the select statement, which sometimes can be useful in this sort of organization. However, it would only be useful if you expected only one of the conditions to be true, or else wanted only one of them to be executed regardless of how many were true - it executes the first one that is true and then leaves.

  • Related