Loops 如何使用&&;SAS中的宏变量
我正在使用SAS,我必须在DO循环中创建一些宏变量。这是我代码的一部分: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;
%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;
另请参阅和,以了解有关多个符号和分辨率的更多信息。另请参阅和,以了解有关多个符号和分辨率的更多信息。