0

对于一个大学研究项目,我正在通过 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 Loop through list of macro variable][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.
4

3 回答 3

1

这条线是错误的。

%local stock = "COP";   

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

%local stock ;
%let stock = "COP";   
于 2018-03-03T20:09:32.607 回答
1

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

首先

%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 命令?仅当您实际上仍在使用显示管理器运行 SAS 时,这才有效。

你想在这里做什么?如果要将日志写入单独的位置,请在使用之前重定向

proc printto log="filename" new; run;

然后关闭它。

proc printto log=log; run;
于 2018-03-03T02:43:02.110 回答
0

我正在使用在 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.

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

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

编辑:我尝试使用 sleep 功能在那里暂停代码,但这仍然不起作用,它给了我错误:

 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 来自我的数据步骤视图。

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

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

解决方案:我不得不添加额外的“运行”;数据步骤之前的语句,然后它起作用(感谢发现这个的理查德)。

于 2018-03-03T21:11:10.327 回答