SAS数据步骤视图和数据包装在宏for循环中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SAS数据步骤视图和数据包装在宏for循环中相关的知识,希望对你有一定的参考价值。

对于大学研究项目,我正在通过SAS从WRDS中检索数据,这对SAS来说相对较新。我试图在WRDS提供的特定时间间隔内检索数据,这对我来说非常有用;结构如下

[1]Define some macro variable
[2]Use data step view
[3]Make manipulation on data
[4]Export the data to csv

特别是我每年检索一只股票的数据。不是一直改变变量,而是允许我提供年份作为输入的宏将是“最优雅”的解决方案(灵感来自这里:[SAS循环通过宏变量列表] [1])。但是,我的宏没有按预期工作(我也改变了结构添加一个追加步骤而不是导出到CSV)。

步骤[3]现在报告错误:ERROR 180-322: Statement is not valid or it is used out of proper order.

我把代码放在这里(第3部分我原样留下因为它创造了问题,另外我缩短了一点(我评论过):

%macro get_stock_ts(list_years);

%local i tables;
%do i=1 %to %sysfunc(countw(&list_years,%str( )));
%let tables=%scan(&list_years,&i,%str( ));

proc datasets lib = work memtype = all nolist;
    delete _:;
quit; 

%local stock = "COP";       

%local taq_ds=taq.&tables:; 
%local filename = &tables._&stock; 

data  _v_&tables / view=_v_&tables;
  set &taq_ds;  
  where symbol = &stock and                             
        (time between '9:30:00't and '16:00:00't) and       
        mode = 12 and                                   
        EX = 'N';                                       
run; 

data xtemp2; 
 set _v_&tables; 
 by symbol date time; 
 format itime rtime time12.; 
 if first.symbol = 1 or first.date = 1 then do;         
    rtime = time; 
    iprice = bid; 
    oprice = ofr; 
    itime = &start_time; 
 end; 

 if time >= itime then do;                                              
       output;                                                          
       itime = itime + &interval_seconds; 
       do while(time >= itime);                                         
           output; 
           itime = itime + &interval_seconds; 
       end; 
end; 
rtime = time; 
iprice = bid; 
oprice = ofr; 
retain itime iprice oprice;                                             
run; 

proc append base = all data = work.xtemp2 force;
run;

proc printto log="/home/Logs/ &filename.log" new; run;
proc printto log=log; run;                                          

%end;
%mend get_stock_ts;

然后我调用例如:

%get_stock_ts(cq_2009)

你知道如何运行代码作为独立工作正常,但是当我将其作为宏包装时,“好”开始产生问题吗?

编辑:我已调整上面的代码并得到以下内容。是因为宏和局部宏变量的语句有问题吗?

 1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 72         
 73         %get_stock_ts(cq_2009)
 ERROR: Invalid symbolic variable name =.
 ERROR: Invalid symbolic variable name "COP".
 ERROR: Invalid symbolic variable name =.
 ERROR: Symbolic variable name TAQ.CQ_2009 must contain only letters,     digits, and underscores.
 ERROR: Invalid symbolic variable name TAQ.CQ_2009.
 ERROR: Invalid symbolic variable name :.
 ERROR: Invalid symbolic variable name =.
 ERROR: Invalid symbolic variable name =.
 ERROR: Invalid symbolic variable name '9:30:00'T.
 ERROR: Invalid symbolic variable name =.
 ERROR: Invalid symbolic variable name 1.
 ERROR: Invalid symbolic variable name *.
 ERROR: Invalid symbolic variable name 60.
 ERROR: Variable symbol is not on file WORK.ALL.

 NOTE: The SAS System stopped processing this step because of errors.
 NOTE: DATA statement used (Total process time):
   real time           0.00 seconds
   cpu time            0.00 seconds

 ERROR: Variable SYMBOL not found.
 ERROR: Variable DATE not found.
 ERROR: Variable TIME not found.
 NOTE: The SAS System stopped processing this step because of errors.
 NOTE: PROCEDURE SORT used (Total process time):
   real time           0.00 seconds
   cpu time            0.00 seconds

 ERROR: File WORK.XTEMP2.DATA does not exist.
答案

不知道你的错误是什么,但宏中的这些行看起来有问题。

第一:

%symdel stock taq_ds filename start_time interval_seconds; */
%let stock = "COP";     
%let taq_ds=taq.&tables:;   
%let filename = &tables._&stock; 
data  _v_&tables / view=_v_&tables;

%SYMDEL的目的是什么?您可能只想制作一些%LOCAL宏变量。当宏结束时,它们将消失。所以不需要删除它们。如果你需要将它们设置为空,那么在%do循环中,那么只需使用%let语句。

你真的想在第一行的末尾开始一个声明风格的评论吗?由于接下来的三行都是宏语句,我认为*会在data语句末尾注释到分号。

第二:

DM 'log; file "/home/ &filename.log" replace'; 
DM "log; clear; ";                                          

你为什么使用DM命令?只有在您使用Display Manager实际运行SAS时,这才有效。

你想在这做什么?如果要将日志写入单独的位置,则使用后重定向BEFORE

proc printto log="filename" new; run;

然后关闭它。

proc printto log=log; run;
另一答案

这条线路错了。

%local stock = "COP";   

您正在尝试定义名为="COP"的本地宏变量。你可能打算这样做。

%local stock ;
%let stock = "COP";   
另一答案

我正在使用工作在WRDS云上的SAS Studio。我意识到以下几点:

当我运行我的代码 - 而不是宏 - “block_by-block”时,一切都运行得很好。如果我运行整个脚本,我在数据xtemp2部分出错:

 73          '9:30:00't and '16:00:00't) and     mode = 12 and            EX =
 73       ! 'N';           run;   *Screen data to find the trade before a set
 73       ! time interval   data xtemp2;       set _v_&tables;       by symbol
                                               ___
                                               180
 73       ! date time;       format itime rtime time12.;       if
 ERROR 180-322: Statement is not valid or it is used out of proper order.

但是,如果我逐块运行我的代码,之后我可以运行整个脚本而不会出现任何问题。

所以我认为解决方案是按顺序运行代码块。是否有可能在代码中“模拟”顺序运行?

编辑:我试图使用睡眠功能暂停代码,但仍然无法正常工作,它给了我错误:

 129        data xtemp2;
 130             set _v_&tables;
 130             set _v_&tables;
                 ___
                 180
 ERROR 180-322: Statement is not valid or it is used out of proper order.
 .
 .
 .

v&tables来自我的数据步骤视图。

编辑:我尝试了睡眠功能,然而,它不起作用。有趣的是,如果我运行所有内容直到数据步骤查看然后从实际数据步骤运行代码字;然后我可以重新运行FULL代码而不是分裂两次。

我将创建一个新的问题,链接回到这个和上面提到的问题,我把代码包装成宏...

解决方案:我不得不添加额外的“运行”;在数据步骤之前的陈述然后它起作用(归功于发现这个的理查德)。

以上是关于SAS数据步骤视图和数据包装在宏for循环中的主要内容,如果未能解决你的问题,请参考以下文章

#SAS#月份循环

数据步骤视图和数据步骤:首先需要“单独”运行以使脚本正常工作

在SAS中使用Arrays for循环

如何更改SAS中所有字符变量的字符长度?

SAS 对变量进行组内编号、循环编号、递增编号和有限重复循环编号

伪代码转换为SAS宏代码