如何在 SAS 中执行 "DO Loop"
How to do "DO Loop" in SAS
我是 SAS 的新手,我在使用 Do Loops 时遇到了问题。下面是代码片段。
DATA _NULL_;
set testing;
do i=_N_ to 4;
call symputx(NAME,"E&_N_");
end;
%PUT =&E&_N_;
run;
我期待它输出以下内容:
E1 = A
E2 = B
E3 = C
E4 = D
但是,我似乎无法让它工作。任何想法我做错了什么?谢谢你的帮助。
首先关注循环问题,重要的是要知道DATA步本身就是一个循环。
给定样本数据:
data have;
input name ;
cards;
A
B
C
D
;
run;
如果你编码:
data _null_;
set have;
run;
您编写了一个循环,数据步循环将迭代五次(而不是四次)。在第一次迭代中,SET 语句读取第一条记录,在第二次迭代中读取第二条记录,...在第五次迭代中,SET 语句尝试读取第五条记录,但它到达了文件末尾和 DATA 步停止。查看此迭代的最简单方法是添加 PUT 语句。:
46 data _null_;
47 put "top of loop " _n_= ;
48 set have;
49 put "bottom of loop " _n_= name= /;
50 run;
top of loop _N_=1
bottom of loop _N_=1 name=A
top of loop _N_=2
bottom of loop _N_=2 name=B
top of loop _N_=3
bottom of loop _N_=3 name=C
top of loop _N_=4
bottom of loop _N_=4 name=D
top of loop _N_=5
NOTE: There were 4 observations read from the data set WORK.HAVE.
有时使用显式 DO 循环读取数据比依赖隐式 do 循环更有用。目前尚不清楚这在这种情况下是否有用,但您可以这样做:
52 data _null_;
53 do _n_=1 to 4;
54 put "top of loop " _n_= ;
55 set have;
56 put "bottom of loop " _n_= name= /;
57 end;
58 run;
top of loop _N_=1
bottom of loop _N_=1 name=A
top of loop _N_=2
bottom of loop _N_=2 name=B
top of loop _N_=3
bottom of loop _N_=3 name=C
top of loop _N_=4
bottom of loop _N_=4 name=D
top of loop _N_=1
NOTE: There were 4 observations read from the data set WORK.HAVE.
在那种情况下,仍然存在隐式数据步循环。但是在隐式 DATA 步循环的第一次迭代中,您在显式 DO 循环中执行四次 SET 语句,读取所有四个记录。在 DATA 步循环的第二次迭代中,SET 语句尝试读取第五条记录并到达文件末尾,因此 DATA 步完成。
了解 DATA 步的隐式循环对于初学者 SAS 程序员来说是必不可少的。大多数人建议初级程序员应该避免学习宏语言,因为它是一种不同于数据步语言的语言。由于宏语言(通常)用于生成 SAS 语言代码,因此在学习宏语言之前,您需要对 SAS 语言有扎实的了解。
也就是说,如果您的目标是创建四个名为 E1 E2 E3 E4 的宏变量,它们将分别解析为值 A B C D,您可以使用 CALL SYMPUTX 来实现。 CALL SYMPUTX 的第一个参数是要创建的宏变量的名称,第二个参数是要分配给宏变量的值。所以你可以这样做:
data _null_;
set have;
call symputx(cats("E",_N_),Name);
run;
%put E1=&E1 E2=&E2 E3=&E3 E4=&E4;
使用 CATS() 函数计算要生成的宏变量的名称(字母 "E" 与 N 的值连接),以及将变量 DATA 步变量 NAME 的值赋给宏变量。还有其他方法可以创建此类宏变量列表(也称为宏变量数组)。重要的是,%PUT 语句在 运行 语句之后。这是因为宏语言语句 %PUT 不是 DATA 步语言的一部分。
我是 SAS 的新手,我在使用 Do Loops 时遇到了问题。下面是代码片段。
DATA _NULL_;
set testing;
do i=_N_ to 4;
call symputx(NAME,"E&_N_");
end;
%PUT =&E&_N_;
run;
我期待它输出以下内容:
E1 = A
E2 = B
E3 = C
E4 = D
但是,我似乎无法让它工作。任何想法我做错了什么?谢谢你的帮助。
首先关注循环问题,重要的是要知道DATA步本身就是一个循环。
给定样本数据:
data have;
input name ;
cards;
A
B
C
D
;
run;
如果你编码:
data _null_;
set have;
run;
您编写了一个循环,数据步循环将迭代五次(而不是四次)。在第一次迭代中,SET 语句读取第一条记录,在第二次迭代中读取第二条记录,...在第五次迭代中,SET 语句尝试读取第五条记录,但它到达了文件末尾和 DATA 步停止。查看此迭代的最简单方法是添加 PUT 语句。:
46 data _null_;
47 put "top of loop " _n_= ;
48 set have;
49 put "bottom of loop " _n_= name= /;
50 run;
top of loop _N_=1
bottom of loop _N_=1 name=A
top of loop _N_=2
bottom of loop _N_=2 name=B
top of loop _N_=3
bottom of loop _N_=3 name=C
top of loop _N_=4
bottom of loop _N_=4 name=D
top of loop _N_=5
NOTE: There were 4 observations read from the data set WORK.HAVE.
有时使用显式 DO 循环读取数据比依赖隐式 do 循环更有用。目前尚不清楚这在这种情况下是否有用,但您可以这样做:
52 data _null_;
53 do _n_=1 to 4;
54 put "top of loop " _n_= ;
55 set have;
56 put "bottom of loop " _n_= name= /;
57 end;
58 run;
top of loop _N_=1
bottom of loop _N_=1 name=A
top of loop _N_=2
bottom of loop _N_=2 name=B
top of loop _N_=3
bottom of loop _N_=3 name=C
top of loop _N_=4
bottom of loop _N_=4 name=D
top of loop _N_=1
NOTE: There were 4 observations read from the data set WORK.HAVE.
在那种情况下,仍然存在隐式数据步循环。但是在隐式 DATA 步循环的第一次迭代中,您在显式 DO 循环中执行四次 SET 语句,读取所有四个记录。在 DATA 步循环的第二次迭代中,SET 语句尝试读取第五条记录并到达文件末尾,因此 DATA 步完成。
了解 DATA 步的隐式循环对于初学者 SAS 程序员来说是必不可少的。大多数人建议初级程序员应该避免学习宏语言,因为它是一种不同于数据步语言的语言。由于宏语言(通常)用于生成 SAS 语言代码,因此在学习宏语言之前,您需要对 SAS 语言有扎实的了解。
也就是说,如果您的目标是创建四个名为 E1 E2 E3 E4 的宏变量,它们将分别解析为值 A B C D,您可以使用 CALL SYMPUTX 来实现。 CALL SYMPUTX 的第一个参数是要创建的宏变量的名称,第二个参数是要分配给宏变量的值。所以你可以这样做:
data _null_;
set have;
call symputx(cats("E",_N_),Name);
run;
%put E1=&E1 E2=&E2 E3=&E3 E4=&E4;
使用 CATS() 函数计算要生成的宏变量的名称(字母 "E" 与 N 的值连接),以及将变量 DATA 步变量 NAME 的值赋给宏变量。还有其他方法可以创建此类宏变量列表(也称为宏变量数组)。重要的是,%PUT 语句在 运行 语句之后。这是因为宏语言语句 %PUT 不是 DATA 步语言的一部分。