SAS使用带有do循环的迭代变量



我有一个样本数据集,我正试图通过do循环从每个观察(记录(创建一个新的数据集。

这是示例代码:

data tst;
input a b;
datalines;
1 2
2 3
;
run;
data ds1 ds2;
set tst 
/*point = point nobs = Nobs*/
;
do i=1 to 2;
call symput("i",i);
%put &=i;
if _n_ then output ds&i.;
end;
run;

我很困惑为什么&i.没有正确解析。在日志中,前面似乎有很多空间。我尝试在ds&i.上使用压缩函数,但没有成功。我知道我可以使用一个宏,在不调用symput((的情况下执行此操作,但我想知道这有什么问题?

理想输出:

DS1:
a b 1 2

DS2:
a b 2 3

这是已知的行为。呼叫症状手册摘录:

在SYMPUT赋值可用之前尝试引用该赋值的问题

使用SYMPUT最常见的问题之一是在创建SYMPUT指定的宏变量值之前尝试引用该值。失败通常是因为引用宏变量的语句在执行分配变量值的CALL SYMPUT语句之前进行编译。在使用SYMPUT时要记住的最重要的事实是,它在程序执行期间分配宏变量的值。宏变量引用在编译步骤、步骤外使用的全局语句或SCL程序期间解析。结果:

在SYMPUT创建宏变量并为其赋值的同一程序(或步骤(中,不能使用宏变量引用来检索该宏变量的值。

在引用程序后面的全局语句(例如TITLE语句(中的值之前,必须指定一个步骤边界语句来强制执行DATA步骤。边界可以是RUN语句或另一个DATA或PROC语句。

这是因为宏变量无法在初始化它的数据步骤中使用。所以我认为你应该使用宏(并修复if语句,在我认为应该做的示例中(:

data tst;
input a b;
datalines;
1 2
2 3
;
run;
%macro output(); %macro d;%mend d;
data ds1 ds2;
set tst 
/*point = point nobs = Nobs*/
;
%do i=1 %to 2;
if mod(_n_,&i)=0 then output ds&i.;
/*if _n_=&i then output ds&i.;*/
%end;
run;
%mend output;
%output();

数据集tst:

+---+---+
| a | b |
+---+---+
| 1 | 2 |
| 2 | 3 |
+---+---+

数据集ds1:

+---+---+
| a | b |
+---+---+
| 1 | 2 |
+---+---+

数据集ds2:

+---+---+
| a | b |
+---+---+
| 2 | 3 |
+---+---+

最新更新