ЛОГИКА УТВЕРЖДЕНИЙ IF

#if-statement #sas #sas-macro

Вопрос:

Это моя логика мышления для моих утверждений if в SAS. Он не работает, потому что мне сказали, что я использую его неправильно. Может ли кто-нибудь оказать помощь, пожалуйста?

ОШИБКА 180-322: Оператор неверен или используется не в правильном порядке.

 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 >= amp;rnd_pct_atl then atl_inda1 = 1; else atl_inda1 = 0;
        if pamt_activity_dr >= amp;rnd_pct_atl then atl_inda2 = 1; else atl_inda2 = 0;
    if b;
        if pamt_activity_cr >= amp;rnd_pct_atl then atl_indb1 = 1; else atl_indb1 = 0;
        if pamt_activity_dr >= amp;rnd_pct_atl then atl_indb2 = 1; else atl_indb2 = 0;
    if c;
        if (ptam/total_Amount) * 100 >= amp;pt_pct_atl then atl_indc = 1; else atl_indc = 0;
    if d;
        if tot_amt_wire >= amp;hrc_wire_amt_atl then atl_indd = 1; else atl_indd1 = 0;
        if tot_in_amt >= amp;wire_in_cnt_amt_atl then atl_indd2 = 1; else atl_indd2 = 0;
        if tot_out_amt >= amp;wire_out_cnt_amt_atl then atl_indd3 = 1; else atl indd3 = 0; 
    if e;
        if tot_amt_lv >= amp;lv_amt_atl then atl_ind = 1; else atl_ind = 0;
    if f;
        if tot_amt_bhvr >= amp;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;
 

Комментарии:

1. Большинство операторов IF с отступом на том же уровне, что и оператор BY, являются ПОДМНОЖЕСТВАМИ операторов IF, а не операторов IF/THEN. В последнем отсутствует конечная точка с запятой. Из-за операторов подмножества IF ваши результаты будут включать только значения CLNT_NO, которые отображаются во всех 6 входных наборах данных. Вы намерены исключить значения CLNT_NO, отсутствующие в одном или нескольких входных наборах данных?

Ответ №1:

if Заявление в SAS всегда имеет следующую форму (без <> ):

 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 >= amp;rnd_pct_atl);
        atl_inda2 = (pamt_activity_dr >= amp;rnd_pct_atl);
    end;

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

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

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

    atl_ind = ( (e AND tot_amt_lv >= amp;lv_amt_atl) OR (f AND tot_amt_bhvr >= amp;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 операторы.

Ответ №2:

if a; является оператором подмножества if и очень часто используется при слияниях, подобных приведенным выше, хотя, вероятно, вы не это имели в виду. Подстановка if означает, что шаг данных должен прекратить выполнение и перейти к следующей строке, если if условие не выполняется.

В случае вышесказанного, if a; true если текущая объединенная строка включает некоторые данные из первого набора данных (который имеет in=a в своих параметрах набора данных).

Хотя нет смысла разбрасывать их вокруг , как вы это сделали, — это наводит на мысль, что вы действительно имеете в виду 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 утверждение, которое иногда может быть полезно в такого рода организации. Однако это было бы полезно только в том случае, если вы ожидали, что только одно из условий будет истинным, или же хотели, чтобы выполнялось только одно из них, независимо от того, сколько из них было истинным — оно выполняет первое, которое является истинным, а затем уходит.