【问题标题】:Problem when including code in a macro在宏中包含代码时出现问题
【发布时间】:2014-08-20 13:13:06
【问题描述】:

我不知道这是否是发布此帖子的正确位置,但在我看来,我更有可能在那里得到答案。

目前正在从事 SAS 实习工作,我正在尝试编写一个宏,以便自动执行为我的数据集寻找合适的 ARIMA 模型的过程。我对这个软件很陌生,而且不是统计学领域的专家。

但是,虽然我似乎了解如何导入文件并启动 proc arima,但我遇到了一个小问题。我的代码的一部分,如果我在宏之外编写它可以正常工作(我猜它被称为open code?)像这样:

data _null_;
set Lib.out;    /* Lib.out contains the data of the OUTSTAT statement of the PROC ARIMA */
x = 1000000;
put _STAT_;     /* Prints correctly the names of the different lines in the log */
if _STAT_='AIC' then do;  /* _STAT_ is a column and AIC the name of a line AFAIK */
    if _VALUE_ < x then
        x = _VALUE_;
    put x;
    put _STAT_;  /* Here only prints AIC, which I guess is correct inside of the IF loop */
end;
run;

但是当在宏中运行它时,例如:

%macro recherche(poste=, mto=);
    --- code ---

data _null_;
set Lib.out;    /* Lib.out contains the data of the OUTSTAT statement of the PROC ARIMA */
%let aic0 = 1000000;
%put _STAT_;     /* Doesn't recognize the _STAT_ statement and stops */
%if _STAT_='AIC' %then %do;
    %if _VALUE_ < &aic0 %then %do;
        &aic0 = _VALUE_;
        data Lib.chosen;
        set Lib.model;   /* Contains the OUTMODEL statement of PROC ARIMA */
        run;
    %end;
end;
run;

    --- code ---

我试图在互联网上搜索类似的案例,但找不到我要查找的内容的解释。另外,作为 SAS 新手,官方文档仍然很难理解。提前致谢。

【问题讨论】:

    标签: sas sas-macro


    【解决方案1】:

    你在那里做的大部分事情都不需要%。如果它是一个控制将哪些代码行发送到编译器的语句,您只需要它。

    %macro recherche(mto=);
    data _null_;
    set Lib.out;    /* Lib.out contains the data of the OUTSTAT statement of the PROC ARIMA */
    x = &mto.;
    put _STAT_;     /* Prints correctly the names of the different lines in the log */
    if _STAT_='AIC' then do;  /* _STAT_ is a column and AIC the name of a line AFAIK */
        if _VALUE_ < x then
            x = _VALUE_;
        put x;
        put _STAT_;  /* Here only prints AIC, which I guess is correct inside of the IF loop */
    end;
    run;
    %mend recherche;
    

    这是假设 MTO 参数旨在保存分配给 x 的值。你唯一会使用 %IF 是如果你做了类似的事情

    %macro recherche(mto=,stat=);
    data _null_;
    set Lib.out;    /* Lib.out contains the data of the OUTSTAT statement of the PROC ARIMA */
    x = &mto.;
    put _STAT_;     /* Prints correctly the names of the different lines in the log */
    %if &stat=AIC %then %do;
      if _STAT_='AIC' then do;  /* _STAT_ is a column and AIC the name of a line AFAIK */
        if _VALUE_ < x then
            x = _VALUE_;
        put x;
        put _STAT_;  /* Here only prints AIC, which I guess is correct inside of the IF loop */
      end;
    %end;
    %else %if &stat=XYZ %then %do;
      *more code ...;
    
    %end;
    run;
    %mend recherche;
    

    这只会执行这些代码部分中的一个或另一个。宏语句无权访问 proc 或 data 步骤中的数据,并且它们不使用引号(除非引号是代码的实际重要部分)。

    【讨论】:

    • 哦,我认为写入宏的每一段代码都必须以某种方式受到% 符号的“保护”。我对您的版本进行了一些修改(poste 是变电站的名称,mto 代表离变电站最近的气象站),但现在编译器似乎无法识别 end; 语句。我收到此错误:There were 2 unclosed DO blocks. 即使我的代码中只有 2 个 DO 块并且它们都像您的示例一样关闭。我会试着看看,看看我能想出什么。
    • 最后,我制作了另一个不需要比较的版本(因此不需要 DO 块)。无论如何,感谢您的解释,这对我来说实际上非常有用。
    【解决方案2】:

    在宏中组合管道语句 do while 循环时遇到了同样的问题。我会得到未闭合的循环错误,但这些语句将独立工作。我尝试了每次迭代来解决,但无济于事。最后,我的解决方案是将管道 infile 语句放入它自己的程序中,然后使用 %include 将其放入宏中。这非常有效!这个问题肯定是 SAS 中的一个错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-24
      • 2011-04-04
      • 2016-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多