SAS:执行while循环不迭代 [英] SAS: Do while loop not iterating

查看:161
本文介绍了SAS:执行while循环不迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个保存的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆