Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 如何使用&&;SAS中的宏变量_Loops_Sas_Sas Macro - Fatal编程技术网

Loops 如何使用&&;SAS中的宏变量

Loops 如何使用&&;SAS中的宏变量,loops,sas,sas-macro,Loops,Sas,Sas Macro,我正在使用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;

我正在使用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;
此代码位于另一个DO循环中,该循环从
i=1运行到&end
。 这样一来,我的宏变量
cont4&&var&i
cont8&&var&i
cont9&&var&i
就会被成本高昂的覆盖……它们在循环之外变得无用。例如,我试着给它们命名为
&&cont4&&var&I
。但显然SAS无法解决宏问题。 实际上,宏是在循环内部创建的,但我不知道在需要外部时如何调用它们

我该怎么修理


提前感谢。

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

%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\uu4。未解决
。好的,让我们添加第二个
&
来延迟宏变量的解析,直到解析
&var1
为止

%put &cont4_&var1;
好吧,这很有帮助,现在它说
CONT4\u AGE not resolved
。为什么不呢?我们用了
调用symput
来定义它,对吗

问题在于范围界定
call symput
可能在本地确定了它的范围,这意味着它是在宏中定义的,而不是在宏之外。为此,我们使用
调用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\u 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\u4&var1
,对吗?这发生在第一关。以下是三个通行证:

&&&&cont4&&var&i
->
&&cont4&&var&1
->
&cont4&uage
->5.26

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

  • &&
    ->
    &
    (并保存以备下次通过)
  • &
    ->解析宏变量
所以,这就是迭代这些的方式。当然,您可以在任何级别显式指定宏变量-因此所有这些工作:

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

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

%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\uu4。未解决
。好的,让我们添加第二个
&
来延迟宏变量的解析,直到解析
&var1
为止

%put &cont4_&var1;
好吧,这很有帮助,现在它说
CONT4\u AGE not resolved
。为什么不呢?我们用了
调用symput
来定义它,对吗

问题在于范围界定
call symput
可能在本地确定了它的范围,这意味着它是在宏中定义的,而不是在宏之外。为此,我们使用
调用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\u 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\u4&var1
,对吗?这发生在第一关。以下是三个通行证:

&&&&cont4&&var&i
->
&&cont4&&var&1
->
&cont4&uage
->5.26

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

  • &&
    ->
    &
    (并保存以备下次通过)
  • &
    ->解析宏变量
所以,这就是迭代这些的方式。当然,您可以在任何级别显式指定宏变量-因此所有这些工作:

%let i=1;
%put &&&&cont4_&&var&i;
%put &&cont4_&var1;
%put &cont4_age;
另请参阅和,以了解有关多个符号和分辨率的更多信息。另请参阅和,以了解有关多个符号和分辨率的更多信息。