我是SAS的新手并且遇到了这个基本问题。我在表A中列出了纽约证券交易所的交易日期,如下所示 -
trading_date
1st March 2012
2nd March 2012
3rd March 2012
4th March 2012
5th March 2012
6th March 2012
我有另一张表B,其股价信息为 -
Date ID Ret Price
1st March 2012 1 … …
3rd March 2012 1 … …
4th March 2012 1 … …
5th March 2012 1 … …
6th March 2012 1 … …
1st March 2012 2 … …
3rd March 2012 2 … …
4th March 2012 2 … …
...包含与价格和退货相关的数字数据。
现在我需要将NYSE Data表连接到上表以获取下表 -
Date ID Ret Price
1st March 2012 1 … …
2nd March 2012 1 0 0
3rd March 2012 1 … …
4th March 2012 1 … …
5th March 2012 1 … …
6th March 2012 1 … …
1st March 2012 2 … …
2nd March 2012 2 0 0
3rd March 2012 2 … …
4th March 2012 2 … …
即。一个简单的左连接。零将被填充。在SAS中表示缺失值,但是你明白了。但是,如果我使用以下命令 -
proc sql;
create table joined as
select table_a.trading_date, table_b.* from table_a LEFT OUTER join table_b on table_a.trading_date=table_b.date;
quit;
仅对第一个ID(即ID = 1)进行连接,而对于其余ID,则保持相同的数据。但我需要为所有ID插入交易日期。
如何在不为所有ID运行do while循环的情况下获取最终数据?由于内存有限,我有1000个ID并且循环并且加入1000次不是一个选项。
答案 0 :(得分:5)
Joe是对的,你需要同时考虑ID,但是使用他的解决方案你不能得到2nd March 2012
,因为当天没有人交易。只需一个sql
步骤即可完成所有操作(这需要更长的时间):
proc sql;
create table final as
select d.trading_date, d.ID, t.Price, t.Ret
from
(
select trading_date, ID
from table_a, (select distinct ID from table_b)
) d
left join
(
select *
from table_b
) t
on t.Date=d.trading_date and t.ID=d.ID
order by d.id, d.trading_date;
quit;
答案 1 :(得分:1)
您的左连接不起作用,因为它不会考虑ID。 SAS(或者说SQL)并不知道它应该通过ID重复。
获得完整组合的最简单方法是PROC FREQ和SPARSE,假设某人在每个有效交易日都有交易。
proc freq data=table_b noprint;
tables id*trading_date/sparse out=table_all(keep=id trading_date);
run;
然后通过id和date将其连接到原始table_b。
或者,您可以使用PROC MEANS,它可以获得数字(它不能以这种方式获取字符,除非您可以将它们用作类值)。
使用Anton创建的table_b(包含ret
和price
变量):
proc means data=table_b noprint completetypes nway;
class id trading_date;
var ret price;
output out=table_allmeans sum=;
run;
这将为当前行的缺失行和值输出缺失,并且将有一个_FREQ_
变量,允许您区分行是否确实存在于交易数据集中。
答案 2 :(得分:-1)
我认为数据必须有一些东西,因为你的查询看起来很好,并且按照你所描述的方式处理我生成的测试数据:
data table_a;
format trading_date date9.;
do trading_date= "01MAR2012"d to "06MAR2012"d;
output;
end;
run;
data table_b;
format date date9.;
ret = 0;
price = 0;
do date= "01MAR2012"d to "06MAR2012"d;
do ID = 1 to 4;
if ranuni(123) < 0.3 then
output;
end;
end;
run;
以下是我逐字复制运行查询后得到的内容:
trading_date date ret price ID
01MAR2012 01MAR2012 0 0 3
02MAR2012 02MAR2012 0 0 2
03MAR2012 03MAR2012 0 0 1
03MAR2012 03MAR2012 0 0 2
04MAR2012 04MAR2012 0 0 2
05MAR2012 05MAR2012 0 0 3
06MAR2012 . . . .
值得检查日期的格式 - 它们是数字吗?如果它们是角色,它们的格式是否相同?如果它们是数字的,它们的日期或日期时间是否应用了一些奇怪的格式?