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