如何在SAS中使用&&宏变量
How to use the && macro variable in SAS
我正在使用 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 没有解决宏。
实际上在循环内部创建了宏,但我不知道在外部需要时如何调用它们。
我该如何解决?
提前致谢。
你这里有很多问题,所以让我们简化一些。这是一个非常简单的例子。例如,这会做一些事情:
%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);
为什么我们需要 四个 &
?好吧,我们需要到达 &&cont4_&var1
,对吧?这发生在第一遍。以下是三个关卡:
&&&&cont4_&&var&i
-> &&cont4_&var1
-> &cont4_age
-> 5.26...
每次通过,都会发生以下情况:
&&
-> &
(并为下一次保存)
&
-> 解析宏变量
所以,这就是您迭代这些内容的方式。您当然可以在任何级别显式指定宏变量 - 所以所有这些工作:
%let i=1;
%put &&&&cont4_&&var&i;
%put &&cont4_&var1;
%put &cont4_age;
我正在使用 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 没有解决宏。
实际上在循环内部创建了宏,但我不知道在外部需要时如何调用它们。
我该如何解决?
提前致谢。
你这里有很多问题,所以让我们简化一些。这是一个非常简单的例子。例如,这会做一些事情:
%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);
为什么我们需要 四个 &
?好吧,我们需要到达 &&cont4_&var1
,对吧?这发生在第一遍。以下是三个关卡:
&&&&cont4_&&var&i
-> &&cont4_&var1
-> &cont4_age
-> 5.26...
每次通过,都会发生以下情况:
&&
->&
(并为下一次保存)&
-> 解析宏变量
所以,这就是您迭代这些内容的方式。您当然可以在任何级别显式指定宏变量 - 所以所有这些工作:
%let i=1;
%put &&&&cont4_&&var&i;
%put &&cont4_&var1;
%put &cont4_age;