Sas 数据集firstobs中存在错误

Sas 数据集firstobs中存在错误,sas,Sas,我对SAS非常、非常陌生,一直在阅读stackoverflow问题和SAS文档,为非常特定的目的编写代码。我一直很难实现我的目标并理解SAS,原因有两个:我只能通过SSH在远程服务器上执行代码,因为我在本地没有SAS(因此,每次更改时,我都需要上传文件,执行并获取日志和lst文件,检查错误)我读到的大多数介绍性主题都不适用于我的任务(我只对使用SAS自动化某个数据提取过程感兴趣) 我的目标是: 读取CSV文件上的某些股票代码(即股票的标识符) 循环每个ticker,通过某些宏检索我需要的信息

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

我的目标是:

  • 读取CSV文件上的某些股票代码(即股票的标识符)
  • 循环每个ticker,通过某些宏检索我需要的信息
到目前为止,我已经成功地读取了.csv并将该数据导入到数据集。为了测试我所需要的基本功能是否正常工作,我编写了以下代码。我的目标是,通过一个循环,将ticker分配给某个“变量”currentticker(可能不是它的正确名称)并打印它。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.
为什么会这样?国际热核实验堆不应该是一个数字,因此作为第一个目标是有效的吗

事先非常感谢

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

编辑2:用于单个股票代码的宏示例。查找必须与&ticker一起提供。将调用lookup,然后是getopt,最后是export_选项卡。这段代码不是我的作者,在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;

您需要在宏变量前面加上
&
,因此
firstobs=&iter.

然而,我不确定你是否真的想这样做。通过对数据集进行宏迭代,您可以通过对数据集进行常规迭代,或者按组使用,来完成几乎所有可能需要执行的操作。与使用内置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排序!)


这基本上是另一个答案,所以把它放在这里。这就是我处理第二部分的方法-根本没有宏。我假设他们的年度数据集已经按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;

一旦读入这些数据,您在SAS中究竟在做什么?如果您只是在做上述工作,那么SAS在这方面就不是一个很好的工具(perl更好,python更好)。如果你在做更复杂的事情,如果你解释一下你在做什么,很可能有更好的方法。你当然可以用我的方法来处理这组宏。基本上,如果
idcodes
数据集包含您想要的所有股票代码的所有idcode,那么其余的代码就可以正常工作。然后,在执行导出时,只需使用
filevar
选项和filename变量中的ticker name将导出从使用
proc export
更改为数据步骤写入(就像我在回答中写的那样)。dlm='09'x,如果希望制表符分隔。请注意,您已将:%do iter=1写入&obscont;实际上,在to前面还需要有一个百分比:%do iter=1%to&obscont;谢谢你的回答。我正在访问WRDS,这是一家研究服务机构,它将几个学术数据库分组,他们自己也建议使用SAS。我不再使用web界面,因为它不允许我执行批处理数据请求,而是寻求使用SAS来自动化我需要的数据提取。所以,我的想法是得到一个我想要提取数据的股票列表,然后一个接一个地索取(我需要单独的文件)。我已经成功地为一只股票使用了一个SAS脚本示例,它执行得相当快,因此就我而言,它似乎是一个不错的替代方案。啊,好的。因此,您可能想做的是创建一个包含所有所需文件的数据集,然后不管您的代码是什么,从WRD中提取文件,将其放入宏中,获取诸如“stock name”之类的参数。然后使用callexecute调用该宏。我将在答案中编辑一个简短的解释。(继续)基本思想是:获取一个ticker列表,然后为每个ticker执行一些宏(尚未编码),以提取我需要的数据-这基本上就是打开.sas文件,执行proc sql将数据限制在我需要的范围内,并输出到.csv文件。我上面列出的一般方法可能是更好的方法-第二种可能是最好的/最有效的,前者是可以的(这是一种更有效的方法来做你想做的事情)。数据步骤将愉快地进行迭代,您无需要求宏来为您完成。感谢您的全面回答,您非常有帮助。代码的某些部分我不完全理解,你能帮我吗?即:第3行:其中lowcase(ticker)in(&tickers.);tickers应该是一个tickers列表,但是如何创建它呢?通过procsql,正如您在上面的答案中所说的那样?第12行:数据批次年份/视图=批次年份;我见过这种用法,但我不明白。在这个上下文中,斜杠(/)是什么意思?另外,我会阅读关于数据合并的内容,因为我还不了解它。啊,我没有提到它的创建-这是我之前的回答,是的,我会把它加回去。该视图正在创建一个数据集视图-与sql视图类似,它实际上并不运行数据,它只存储您希望如何运行数据,以供以后使用。这就是创建它的方式-
data/viewproc 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;