SAS:执行while循环不迭代 [英] SAS: Do while loop not iterating
问题描述
我有一个保存的 csv_files
SAS数据集,其中包含以下条目:
名称路径
aapl F:\Data\aapl.csv
msft F:\Data\msft.csv
ibm F:\Data\ibm.csv
goog F:\Data\goog.csv
然后我使用此SAS数据集找到csv文件,然后使用以下具有 while
循环的宏将其导入SAS:
options symbolgen mlogic nomprint;
/ *当Do While循环为false时,保留选项为SAS会发出一条消息* /
%let dsname = csv_files;
%let libto = l;
%宏get_data(n,index);
/ * n:是一个计数宏变量,表示要读入SAS的CSV文件
的下限。索引:是一个变量,可以看作是
观察号(行号),代表要读入SAS的CSV文件数量的上限
。* /
%DO%WHILE(& n< =& index);
data _NULL_;
set& libto ..& dsname end = last;
如果_N_ =& n,则执行Do;
呼叫symput('path',path); / *从CSV_files * /
调用symput('dsn',name)中获取文件路径; / *从CSV_files * /
获取数据集名称(如果不是最后一个,则为index + 1); / *创建宏变量索引* /
否则,如果最后一次调用symput(索引,索引);
结束;
运行;
proc导入数据文件=& path
out =& libto ..& dsn
dbms = dlm
replace;
delimiter =,;
getnames = yes;
运行;
%End;
%修改get_data;
/ *宏调用* /
%get_data(1,4);
执行此宏时,我总是在第一个观察值上进行迭代(在本例中为AAPL)。它只是一遍又一遍地导入aapl.csv文件。...怎么了?
更新
按照Dmitry Shopin的建议,我将期间
更改为 do
循环:
%let dsname = csv_files;
%let libto = l;
%宏get_data(n,index);
%let dsname = csv_files;
%let libto = l;
%do i =& n%to& index;
data _NULL_;
set& libto ..& dsname end = last;
如果_N_ =& i,则执行Do;
呼叫symput('path',path); / *从CSV_files * /
调用symput('dsn',name)中获取文件路径; / *从CSV_files * /
获取数据集名称(如果不是最后一个,则为index + 1); / *创建宏变量索引* /
否则,如果最后一次调用symput(索引,索引);
结束;
运行;
proc导入数据文件=& path
out =& libto ..& dsn
dbms = dlm
replace;
delimiter =,;
getnames = yes;
运行;
%End;
%End;
%修改get_data;
/ *宏调用* /
%get_data(1,4);
我得到的错误如下:
错误180-322:语句无效或使用顺序不正确。
我在代码中得到多行,但是从我的4个SAS数据集中生成了最后3个CSV文件。
在代码中,我也收到& dsn
的错误:
错误22-322:语法错误,期望以下之一:;,(,DATAFILE,DATATABLE,DBMS,
DEBUG,FILE ,OUT,REPLACE,TABLE,_DEBUG_。
也许这是因为您不每次迭代都增加& n宏变量吗?我建议您替换
%DO%WHILE ...
具有
<$ p $的循环p>
%DO i =& n%TO& index;
...
如果_N _ =& i然后...;
更新
这就是我运行的并且有效的。您问题中的更新代码相同,除了:
-我添加了数据步骤以创建csv_files数据集
-我删除了第二个%END语句
添加的LIBNAME来分配l库
更改了F :-驱动器到C:-驱动器的路径中(只是因为我没有F驱动器):
libname l 'C:\数据';
data l.csv_files;
长度名称$ 4路径$ 20;
输入名称$ path $;
条数据线;
aapl C:\Data\aapl.csv
msft C:\Data\msft.csv
ibm C:\Data\ibm.csv
goog C:\Data\goog.csv
;
运行;
%let dsname = csv_files;
%let libto = l;
%宏get_data(n,index);
%let dsname = csv_files;
%let libto = l;
%do i =& n%to& index;
data _NULL_;
set& libto ..& dsname end = last;
如果_N_ =& i,则执行Do;
呼叫symput('path',path); / *从CSV_files * /
调用symput('dsn',name)中获取文件路径; / *从CSV_files * /
获取数据集名称(如果不是最后一个,则为index + 1); / *创建宏变量索引* /
否则,如果最后一次调用symput(索引,索引);
结束;
运行;
proc导入数据文件=& path
out =& libto ..& dsn
dbms = dlm
replace;
delimiter =,;
getnames = yes;
运行;
%End;
%修改get_data;
/ *宏调用* /
%get_data(1,4);
I have a saved csv_files
SAS Dataset with the following entries:
name path
aapl F:\Data\aapl.csv
msft F:\Data\msft.csv
ibm F:\Data\ibm.csv
goog F:\Data\goog.csv
I then use this SAS dataset to locate the csv files and import them into SAS using the following Macro which has a while
loop:
options symbolgen mlogic nomprint;
/*Leave options on as SAS will issue a message when Do While Loop is false*/
%let dsname = csv_files;
%let libto = l;
%Macro get_data(n,index);
/*n: is a counting macro variable representing the lower limit of the number of CSV files
to be read into SAS. Index: is a variable that can be thought of as
observation number( row number) representing the upper limit
of the number of CSV files to be read into SAS.*/
%DO %WHILE (&n <=&index);
data _NULL_;
set &libto..&dsname end=last;
if _N_ =&n then Do;
call symput('path',path); /* Get file path from CSV_files*/
call symput('dsn',name); /* Get dataset name from CSV_files*/
if not last then index+1; /* Create macro variable Index */
else if last then call symput ('index',index);
End;
run;
proc import datafile= "&path"
out= &libto..&dsn
dbms=dlm
replace;
delimiter="," ;
getnames=yes;
run;
%End;
%Mend get_data;
/* Macro Call*/
%get_data(1,4);
When I execute this Macro I always iterate over the first observation (in this case AAPL). It simply imports the aapl.csv file over and over....what's wrong?
UPDATE
Following the suggestion of Dmitry Shopin I changed my while
for a do
loop:
%let dsname = csv_files;
%let libto = l;
%Macro get_data(n,index);
%let dsname = csv_files;
%let libto = l;
%do i=&n %to &index;
data _NULL_;
set &libto..&dsname end=last;
if _N_ =&i then Do;
call symput('path',path); /* Get file path from CSV_files*/
call symput('dsn',name); /* Get dataset name from CSV_files*/
if not last then index+1; /* Create macro variable Index */
else if last then call symput ('index',index);
End;
run;
proc import datafile= "&path"
out= &libto..&dsn
dbms=dlm
replace;
delimiter="," ;
getnames=yes;
run;
%End;
%End;
%Mend get_data;
/* Macro Call*/
%get_data(1,4);
The errors that I get is the following:
ERROR 180-322: Statement is not valid or it is used out of proper order.
I get this for multiple lines in the code but generates the last 3 out of 4 SAS datasets from my CSV files.
I also get the error for the &dsn
in the code:
ERROR 22-322: Syntax error, expecting one of the following: ;, (, DATAFILE, DATATABLE, DBMS,
DEBUG, FILE, OUT, REPLACE, TABLE, _DEBUG_.
Maybe, it's because you don't increment your &n macrovariable with every iteration? I would suggest to replace your
%DO %WHILE...
loop with
%DO i=&n %TO &index;
...
if _N_=&i then ...;
UPDATE
This is what I run and it worked. It's exactly the same updated code from your question, except:
-I added data step to create csv_files dataset
-I deleted the second %END statement
-added LIBNAME to assign l library
-changed F:-drive to C:-drive in the paths (just because I don't have F-drive):
libname l 'C:\Data';
data l.csv_files;
length name $4 path $20;
input name $ path $;
datalines;
aapl C:\Data\aapl.csv
msft C:\Data\msft.csv
ibm C:\Data\ibm.csv
goog C:\Data\goog.csv
;
run;
%let dsname = csv_files;
%let libto = l;
%Macro get_data(n,index);
%let dsname = csv_files;
%let libto = l;
%do i=&n %to &index;
data _NULL_;
set &libto..&dsname end=last;
if _N_ =&i then Do;
call symput('path',path); /* Get file path from CSV_files*/
call symput('dsn',name); /* Get dataset name from CSV_files*/
if not last then index+1; /* Create macro variable Index */
else if last then call symput ('index',index);
End;
run;
proc import datafile= "&path"
out= &libto..&dsn
dbms=dlm
replace;
delimiter="," ;
getnames=yes;
run;
%End;
%Mend get_data;
/* Macro Call*/
%get_data(1,4);
这篇关于SAS:执行while循环不迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!