IF 语句逻辑

IF STATEMENTS LOGIC

这是我对 SAS 中的 if 语句的思考逻辑。它不是 运行 因为有人告诉我我使用不当。有人可以提供帮助吗?

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;

SAS 中的 if 语句始终具有以下形式(没有 <>):

if <boolean logic> then <code>;

如果评估的逻辑需要做不止一件事,它遵循这种形式:

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

看起来您的所有代码都创建了二进制变量。 SAS 中的这个编程快捷方式将为您生成二进制 1/0 变量:

binary_var = (<boolean logic>);

如果逻辑为真,binary_var为1,否则为0。

下面是您的代码的正确形式以及新二进制变量的更清晰形式。

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;

从技术上讲,您在这里甚至不需要 if 语句。您可以将数据集 in 逻辑合并到每个二进制变量中(例如 binary_var = (a AND <logic>);。如果此操作不需要缺失值,您可以完全删除那些 if 语句。

if a; 是一个 subsetting if 语句,并且在像上面这样的合并中非常常用 - 虽然可能不是你 的意思 。子集 if 意味着如果 if 条件不成立,数据步骤应该停止执行并转到下一行。

在上述情况下,如果当前合并行包含来自第一个数据集(其数据集选项中具有 in=a)的一些数据,则 if a;true

像你那样把它们撒在周围是没有意义的——这表明你真正的意思是 if it comes from a then do these things,而不是 if it doesn't come from a then drop it

此外,对于所有六个 (if a; if b; if c;...),只有在所有六个输入数据集中都具有某些值的行才会被保留 - inner join - 然后你的最后一部分没有意义(带有 or 的那个)。但这样做更有意义:

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


另一个注意事项:select 语句有时在这种组织中很有用。但是,它只有在您期望 只有一个 条件为真时才有用,或者希望 只有一个 被执行有多少是真的 - 它执行第一个是真的然后离开。