首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在SAS中使用&&宏变量

如何在SAS中使用&&宏变量
EN

Stack Overflow用户
提问于 2016-08-25 14:34:55
回答 1查看 4K关注 0票数 0

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

代码语言:javascript
复制
%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是远距离的overwrited...and,它们在循环之外变得无用。例如,我试着给它们取名为&&cont4_&&var&i。但很明显,SAS并不能解决宏观问题。实际上,在循环内部创建了宏,但我不知道如何在需要时调用它们。

我怎么才能修好?

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-25 15:00:52

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

代码语言:javascript
复制
%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)

但现在如果我们这么做

代码语言:javascript
复制
%put cont4_&&var&i;

当然它不起作用,因为&i没有任何意义。相反,我们用,比如说,1:

代码语言:javascript
复制
%put cont4_&&var1;

现在我们得到了一些东西。但是我们没有得到任何有用的东西,不是吗,只是变量名。但是-至少这是件好事!

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

代码语言:javascript
复制
%put cont4_&var1;

但是,在此之前,我们需要一个&来使用宏变量:

代码语言:javascript
复制
%put &cont4_&var1;

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

代码语言:javascript
复制
%put &cont4_&var1;

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

问题在于界定范围。call symput可能在本地定义了它的作用域,这意味着它是在宏中定义的,而不是在宏之外定义的。为此,我们使用call symputx并给它一个全局范围。

代码语言:javascript
复制
%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。否则,它将只在本地可用--在宏中--并且将被清理。

现在,这起作用是:

代码语言:javascript
复制
%put &&cont4_&var1;

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

以下是起作用的原因:

代码语言:javascript
复制
%macro iterate_i(var_count=);
  %do i = 1 %to &var_count.;
    %put &&&&cont4_&&var&i.;
  %end;
%mend iterate_i;

%iterate_i(var_count=3);

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

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

每过一次,就会发生以下情况:

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

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

代码语言:javascript
复制
%let i=1;
%put &&&&cont4_&&var&i;
%put &&cont4_&var1;
%put &cont4_age;
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39148162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档