【问题标题】:How to use the && macro variable in SAS如何在 SAS 中使用 && 宏变量
【发布时间】:2016-08-25 14:34:55
【问题描述】:

我正在使用 SAS,我必须在 DO 循环中创建一些宏变量。这是我的代码的一部分:

%if &dsempty888=0 %then %do;
    data _null_;
    set freq_&&var&i;
        if &&var&i=888888888 then do;
            call symput("cont8_&&var&i",percent);
        end;
    run;
%end;
%if &dsempty888=1 %then %do;
    %let cont8_&&var&i=0;
%end;

%if &dsempty999=0 %then %do;
    data _null_;
    set freq_&&var&i;
        if &&var&i=999999999 then do;
            call symput("cont9_&&var&i",percent);
        end;
    run;
%end;
%if &dsempty999=1 %then %do;
    %let cont9_&&var&i=0;
%end;


%if &dsempty444=0 %then %do;
    data _null_;
    set freq_&&var&i;
        if &&var&i=444444444 then do;
            call symput("cont4_&&var&i",percent);
        end;
    run;
%end;
%if &dsempty444=1 %then %do;
    %let cont4_&&var&i=0;
%end;

此代码位于另一个从 i=1 to &end 运行的 DO 循环中。 有了这个,我的宏变量cont4_&&var&icont8_&&var&icont9_&&var&i 被大量覆盖......并且它们在循环之外变得无用。例如,我试图将它们命名为 &&cont4_&&var&i。但显然 SAS 并没有解决宏观问题。 实际上,宏是在循环内部创建的,但我不知道在需要外部时如何调用它们。

我该如何解决?

提前致谢。

【问题讨论】:

标签: loops sas sas-macro


【解决方案1】:

这里有很多问题,所以让我们简化一下。这是一个非常简化的示例。例如,这会做一些事情:

%let var1 = age;
%let var2 = height;
%let var3 = weight;

proc freq data=sashelp.class noprint;
  tables age/out=freq_age;
  tables height/out=freq_height;
  tables weight/out=freq_weight;
run;


%macro get_freqs(var_count=);
  %do i = 1 %to &var_count.;
      data _null_;
        set freq_&&var&i;
        call symput("cont4_&&var&i",percent);
      run;
  %end;
%mend get_freqs;

%get_Freqs(var_count=3)

但现在如果我们这样做

%put cont4_&&var&i;

当然不行,因为&i 没有意义。因此,我们将其替换为 1:

%put cont4_&&var1;

现在我们得到了一些东西。但是我们没有得到任何有用的东西,对吧,只是变量名。但是 - 至少是这样!

现在我们真的不需要第二个&,对吧?

%put cont4_&var1;

但在此之前我们需要一个& 才能使用宏变量:

%put &cont4_&var1;

但现在我们收到一条警告消息,CONT4_ not resolved。好的,让我们添加第二个& 来延迟宏变量的解析,直到&var1 被解析。

%put &cont4_&var1;

嗯,这很有帮助,现在它显示为 CONT4_AGE not resolved。为什么不?我们使用call symput 来定义它,对吗?

问题在于范围call symput 可能将其限定在本地范围内,这意味着它是在宏中定义的,而不是在宏之外定义的。为此,我们使用call symputx 并赋予它一个全局范围。

%macro get_freqs(var_count=);
  %do i = 1 %to &var_count.;
      data _null_;
        set freq_&&var&i;
        call symputx("cont4_&&var&i",percent,'g');
      run;
  %end;
%mend get_freqs;

这告诉 SAS 我希望在宏之外定义&cont4_age。否则它将仅在本地可用 - 在宏内部 - 并且将被清理。

现在,这可行:

%put &&cont4_&var1;

但是,如果您想再次迭代 &i,它会更复杂。那是因为您需要多次延迟这些 & 符号,并允许多次通过。

以下是有效的:

%macro iterate_i(var_count=);
  %do i = 1 %to &var_count.;
    %put &&&&cont4_&&var&i.;
  %end;
%mend iterate_i;

%iterate_i(var_count=3);

为什么我们需要四个 &s?好吧,我们需要去&&cont4_&var1,对吧?这发生在第一遍。以下是三个通行证:

&&&&cont4_&&var&i -> &&cont4_&var1 -> &cont4_age -> 5.26...

每次通过,都会发生以下情况:

  • && -> &(并保存到下一次)
  • & -> 解析宏变量

所以,这就是您迭代这些的方式。您当然可以在任何级别显式指定宏变量 - 所以所有这些工作:

%let i=1;
%put &&&&cont4_&&var&i;
%put &&cont4_&var1;
%put &cont4_age;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    相关资源
    最近更新 更多