逻辑离开环路不工作SAS



我想重复一些代码,改变其中一个参数并测试是否满足条件。如果满足条件,我想退出循环,如果不满足,我想继续到参数的下一个值。我使用的是下面的代码,它工作得很好,只是它不会在我期望的时候离开循环。尽管摘要显示应该满足条件,但它似乎总是解析为False。

%macro set_downward_caps(year, in_year_tolerance, large, small, start, end, increment);
%do c = &start. %to &end. %by &increment.;
    %let nominal_down_large_&year. = %sysevalf(&large. + (&c. / 1000));
    %let nominal_down_small_&year. = %sysevalf(&small. + (&c. / 100));
    %let real_down_large_&year. = %sysevalf((1 - &&nominal_down_large_&year.) * &&rpi&year.);
    %let real_down_small_&year. = %sysevalf((1 - &&nominal_down_small_&year.) * &&rpi&year.);
    %rates(&year.);
    proc means data = output.s_&scenario. noprint nway;
        var transbill&year.;
        output out = temporary (drop = _type_ _freq_) sum=cost;
    run;
    data _null_;
        set temporary;
        call symput('cost', cost);
    run;
    data temp;
        length scenario $ 30;
        scenario = "&scenario.";
        large = &&real_down_large_&year.;
        small = &&real_down_small_&year.;
        cost = &cost.;
    run;
    data output.summary_of_caps;
        set output.summary_of_caps temp;
    run;
    %if %sysfunc(abs(&cost.)) le &in_year_tolerance. %then leave;
%end;
%mend set_downward_caps;

因此sumary_of_caps表包含的值表明以下条件应该已解析为true:

%if %sysfunc(abs(&cost.)) le &in_year_tolerance. %then leave;

我试着把它放在sysevalf中,但没有用。

我认为宏代码没有等效的LEAVE。为什么不直接使用%GOTO?或者,由于您似乎想完全离开宏,您可以使用%RETURN

此外,如果您正在比较浮点数,则需要使用%SYSEVALF()%IF语句的隐含%EVAL()调用将仅处理整数运算。

%if %sysevalf(%sysfunc(abs(&cost)) le &in_year_tolerance) %then %return;

为什么要在宏逻辑中进行计算?我不知道为什么你有所有这些宏变量,除非%RATES()宏正在引用它们?但是,如果它需要它们,为什么它们不像您在&YEAR中传递的那样成为宏的参数呢?

在当前代码中有大量的数据步骤,您可以在其中进行计算,并设置一个标志变量,用于控制是否退出循环。

%macro set_downward_caps
(year
,in_year_tolerance
,large
,small
,start
,end
,increment
);
%local c leave ;
%do c = &start %to &end %by &increment;
    %local nominal_down_large_&year ;
    %local nominal_down_small_&year ;
    %local real_down_large_&year ;
    %local real_down_small_&year ;
    %let nominal_down_large_&year. = %sysevalf(&large. + (&c. / 1000));
    %let nominal_down_small_&year. = %sysevalf(&small. + (&c. / 100));
    %let real_down_large_&year. = %sysevalf((1 - &&nominal_down_large_&year.) * &&rpi&year.);
    %let real_down_small_&year. = %sysevalf((1 - &&nominal_down_small_&year.) * &&rpi&year.);
    %rates(&year.);
    proc means data = output.s_&scenario. noprint nway;
        var transbill&year.;
        output out = temporary sum=cost;
    run;
    data temp;
        length scenario $ 30;
        scenario = "&scenario.";
        large = &&real_down_large_&year.;
        small = &&real_down_small_&year.;
        set temporary (keep=cost);
        call symputx('leave',abs(cost) le &in_year_tolerance);
        put (_all_) (=);
    run;
    data output.summary_of_caps;
        set output.summary_of_caps temp;
    run;
    %if (&leave) %then %goto quit;
%end;
%quit:
%mend set_downward_caps;

最新更新