数据集firstobs出错

时间:2014-01-10 17:45:29

标签: sas

我对SAS非常非常新,并且一直在阅读stackoverflow问题和SAS文档,为特定目的编写代码。我一直很难实现我的目标并理解SAS有两个原因:我只能通过SSH在远程服务器上执行代码,因为我本地没有SAS(因此,在每次更改时,我都需要上传文件,执行并获取log和lst文件,检查错误)我读过的大多数介绍性主题都不能立即适用于我的任务(我只对使用SAS自动执行某个数据提取过程感兴趣)。

我的目标是:

  • 读取CSV文件中的某些代码(即股票的标识符);
  • 循环每个自动收报机,通过某些宏检索我需要的信息。

到目前为止,我已成功读取.csv并将该数据导入数据集。为了测试我需要的基础是否正常工作,我做了以下代码。我的目标是,通过一个循环,将自动收报机分配给某个“变量”当前标签(可能不是它的正确名称)并打印出来。 csv文件只有两行,第一行是“IBM”,另一行是“DELL”。

libname mydir '~/';

data companies;
  infile 'sastests/data/tickers.csv' delimiter=',';
  input ticker $;
run;

proc sql;
 select    count(*)
 into      :OBSCOUNT
 from      companies;
quit;

proc print data=companies;
  var ticker;
run;

%do iter = 1 to &OBSCOUNT;
  data currentticker;
    set companies (firstobs = iter obs = iter);
  run;
  proc print data = currentticker;
  run;
%end;

当我查看日志文件时,我立即在数据集的第一个firstobs选项中收到错误。

Invalid value for the FIRSTOBS option.

为什么会这样?它不应该是一个数字,因此作为FIRSTOBS有效吗?

非常感谢你。

编辑1:标题不是对问题的良好描述。

编辑2:用于单个股票代码的宏的示例。必须使用& ticker来查找。将调用lookup,然后是getopt,最后是export_tab。这段代码不是我的作者,我在WRDS作为示例代码提供之后稍作修改。

%macro lookup;

  data idcodes (keep=secid);
  set optionm.secnmd;
  where lowcase(ticker) = &ticker;

  proc sort data=idcodes nodupkey;
    by secid;

  proc print data=idcodes;

%mend;

%macro getopt(year);

  proc sql;
    create table temp as
      select a.* 
      from
        optionm.vsurfd&year as a,
        idcodes as b
      where
        a.secid = b.secid;
  run;

  proc datasets;
    append base=work.&outputfile
    data=work.temp;
  run;

%mend;

%macro export_tab;

  proc export data=&outputfile outfile="&outputfile._out.txt" dbms=tab replace;
  run;

%mend;

2 个答案:

答案 0 :(得分:1)

您需要在&之前的宏变量之前,firstobs=&iter.

但是,我不确定你真的想这样做。通过对数据集进行宏迭代,您可以通过对数据集进行常规迭代,并且可能使用BY组来完成您可能想要做的任何事情。与使用内置SAS技术相比,宏迭代的效率非常低。

要为数据集中的每一行调用一组代码,您可以执行以下操作。

%macro pulldata(ticker);
data stock_data;
set big_database;
where ticker="&ticker";
file "c:\mydir\myfile_&ticker..csv" dlm=',' lrecl=32767; *double period - first is macro variable delimiter;
put (_all_) ($);
run;
%mend pulldata;

data _null_;
set companies;
call execute('%pulldata(',ticker,')');
run;

您也可以这样做,我们使用filevar选项允许将数据集放到多个文件中(必须按filevar排序!)

proc sql;
select quote(ticker) into :tickerlist separated by ',' from companies;
quit;

data mydata;
set bigdata;
where ticker in (&tickerlist.);
filen = cats('c:\mydata\myfile_',ticker,'.csv');
run;

proc sort data=mydata;
by filen;
run;

data _null_;
set mydata;
file a filevar=filen dlm=',' lrecl=32767;
put (_all_) ($);
run;

答案 1 :(得分:0)

这基本上是另一个答案,所以把它放在这里。这就是我接近第二部分的方法 - 根本没有宏。我假设他们的年度数据集已经由secid排序;如果没有,这可能会有点复杂,只是为了避免合并。

proc sql;
select quote(ticker) into :tickerlist separated by ',' from companies;
quit;

data idcodes;  *you could also create this by merging optiomn.secnmd to companies by ticker.;
set optionm.secnmd;
where lowcase(ticker) in (&tickers.);
run;

proc sort data=idcodes nodupkey;
by secid;
run;

proc print data=idcodes;
run;

data lotsofyears/view=lotsofyears;
set
optionm.vsurfd2010
optionm.vsurfd2011
optionm.vsurfd2012
optionm.vsurfd2013
;  *or however many you need, you could generate this list if it is long;
by secid;
run;

data mydata;
merge lotsofyears(in=a) idcodes(in=b);
by secid;
filenm=cats("c:\mydir\mydata_",ticker,".dat"); *or secid if that is better;
run;
proc sort data=mydata;
by ticker;
run;
data _null_;
set mydata;
file a filevar=filenm dlm='09'x lrecl=32767;
put (_all_)($); *or perhaps a more complex put statement - see what proc export generates;
run;