我正在使用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&i
cont8_&&var&i
cont9_&&var&i
被彻底淹没......并且它们在循环之外变得无用。我试图将它们命名为&&cont4_&&var&i
。但显然SAS并没有解决这个问题。
在循环内部实现了宏的创建,但是当我需要外部时,我不知道如何调用它们。
我该如何解决?
提前致谢。
答案 0 :(得分:4)
您在这里遇到了很多问题,所以让我们简化一下。这是一个非常简单的例子。例如,这可以做一些事情:
Take-Ownership
但现在我们做了
%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;
没有意义。所以我们用1:
&i
现在我们得到了一些东西。但是我们没有任何有用的东西,我们只是变量名称。但是 - 至少那是什么东西!
现在我们真的不需要第二个%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
这告诉SAS我希望在宏之外定义%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;
。否则它只能在本地 - 宏内部 - 并且将被清理。
现在,这有效:
&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);
?好吧,我们需要到&
,对吧?这发生在第一遍。以下是三遍:
&&cont4_&var1
- > &&&&cont4_&&var&i
- > &&cont4_&var1
- > 5.26 ...
每次通过,发生以下情况:
&cont4_age
- > &&
(并保存下次通行证)&
- >解决宏变量那么,那就是你如何迭代这些。您当然可以在任何级别明确指定宏变量 - 所以这些都可以工作:
&