SAS Collating/summarizing 个时间间隔内的观测值
SAS Collating/summarizing observations over a time interval
我有一组交易数据,以毫秒为单位进行观察,但频率不高。为了使其成为合理的时间序列,我创建了一个宏来构建网格(每秒一次观察)。现在我希望我的数据集适合网格(总结那一秒发生的交易量并使用最后的 quote/trade 价格。
我非常感谢任何想法。请参阅下面的代码。
最佳
%macro makeGrid;
proc sort data=data.inputdataset; by id date milliseconds descending type order; run;
options nomprint;
data data.outputgrid (keep=id date miliseconds type order);
set data.inputdataset;
by id date;
if first.date;
Type="grid"; Order=0;
%do i=((9*60*60)+(10*60)) %to ((16*60*60)+(50*60));
milliseconds=&i; output;
%end;
run;
options mprint;
%mend makeGrid;
一个非常绝望的尝试是这样的:
data data.merged;
merge data.outputgrid data.inputdataset;
by id date milliseconds;
if first.id then do;
if milliseconds collate = sum(volume)
run;
网格:
ID date time price volume
ABC 01/01/15 0801000
ABC 01/01/15 0802000
ABC 01/01/15 0803000
ABC 01/01/15 0804000
数据示例:
ID date time price volume
ABC 01/01/15 0800004 1,55 100
ABC 01/01/15 0800110 1,56 200
ABC 01/01/15 0800152 1,52 300
ABC 01/01/15 0800210 1,51 400
ABC 01/01/15 0800352 1,50 200
ABC 01/01/15 0800384 1,51 400
输出:
ID date time price volume
ABC 01/01/15 0801000 1,55 100
ABC 01/01/15 0802000 1,52 500
ABC 01/01/15 0803000 1,51 400
ABC 01/01/15 0804000 1,51 600
如果那一秒没有交易,成交量应为 0,价格为最后一秒的价格。
编辑:
所以,感谢 Chris,我制作了没有宏的网格,但是过程 SQL 没有按我想要的那样工作。
data grid1;
do seconds = '09:10't to '16:50't ;
output ;
end ;
/* id=.;*/
/* date=.;*/
/* format ric . ;*/
/* format Date best12. ;*/
run;
proc sql ;
create table want as
select a.id, a.date, a.miliseconds, sum(a.volume) as Volume
from have a
left join
grid1 b on a.id = b.id
and a.date = b.date
and a.miliseconds = floor(b.seconds)
group by a.id, a.date, a.miliseconds ;
quit;
run;
所以,找不到id和date,所以我在数据步骤中创建了它们。但是 id 不是相同的格式,我试图修复但失败了。
通过匹配秒网格线之间的毫秒数将拥有的数据集合并到想要的数据集时,我似乎遇到了错误。
我错过了什么?永远感谢您的投入!
最佳
首先,为什么要使用宏来创建一秒间隔?
do time = '09:10't to '16:50't ;
output ;
end ;
假设你的milliseconds
只是小数点后3位的时间,只需将floor(time)
加入相应的区间,然后总结。
proc sql ;
create table want as
select a.id, a.date, a.time, sum(b.volume) as Volume
from grid a
left join
inputdataset b on a.id = b.id
and a.date = b.date
and a.time = floor(b.time)
group by a.id, a.date, a.time ;
quit ;
然后您可以 post 处理此数据集,将缺失的交易量设置为零或相应地保留之前的价格。
首先感谢大家的回答。
我想出了怎么做。可能有更简单的方法,但对我来说,现在就足够了:
data data.test;
set data.taq;
next_full_sec = int((miliseconds-1) / 1000) + 1;
run;
data data.grid;
do seconds = 1 to 86400;
output;
end;
run;
proc summary data=data.test;
by ric date time next_full_sec;
var volume;
output out=data.int (drop=_type_) sum=;
run;
proc sort data=data.test (keep=ric date) out=data.id_date nodupkey;
by ric date time;
run;
proc sql;
create table data.testseconds as
select ric, date, time, seconds
from data.id_date, data.grid
order by ric, date, time, seconds
;
quit;
data data.testout;
merge
data.testseconds (in=a rename=(fullseconds=next_full_sec))
data.int (in=b)
;
by ric date time next_full_sec;
if a;
if not b
then do;
_freq_ = 0;
volume = 0;
end;
run;
proc print noobs;
run;
我有一组交易数据,以毫秒为单位进行观察,但频率不高。为了使其成为合理的时间序列,我创建了一个宏来构建网格(每秒一次观察)。现在我希望我的数据集适合网格(总结那一秒发生的交易量并使用最后的 quote/trade 价格。 我非常感谢任何想法。请参阅下面的代码。
最佳
%macro makeGrid;
proc sort data=data.inputdataset; by id date milliseconds descending type order; run;
options nomprint;
data data.outputgrid (keep=id date miliseconds type order);
set data.inputdataset;
by id date;
if first.date;
Type="grid"; Order=0;
%do i=((9*60*60)+(10*60)) %to ((16*60*60)+(50*60));
milliseconds=&i; output;
%end;
run;
options mprint;
%mend makeGrid;
一个非常绝望的尝试是这样的:
data data.merged;
merge data.outputgrid data.inputdataset;
by id date milliseconds;
if first.id then do;
if milliseconds collate = sum(volume)
run;
网格:
ID date time price volume
ABC 01/01/15 0801000
ABC 01/01/15 0802000
ABC 01/01/15 0803000
ABC 01/01/15 0804000
数据示例:
ID date time price volume
ABC 01/01/15 0800004 1,55 100
ABC 01/01/15 0800110 1,56 200
ABC 01/01/15 0800152 1,52 300
ABC 01/01/15 0800210 1,51 400
ABC 01/01/15 0800352 1,50 200
ABC 01/01/15 0800384 1,51 400
输出:
ID date time price volume
ABC 01/01/15 0801000 1,55 100
ABC 01/01/15 0802000 1,52 500
ABC 01/01/15 0803000 1,51 400
ABC 01/01/15 0804000 1,51 600
如果那一秒没有交易,成交量应为 0,价格为最后一秒的价格。
编辑:
所以,感谢 Chris,我制作了没有宏的网格,但是过程 SQL 没有按我想要的那样工作。
data grid1;
do seconds = '09:10't to '16:50't ;
output ;
end ;
/* id=.;*/
/* date=.;*/
/* format ric . ;*/
/* format Date best12. ;*/
run;
proc sql ;
create table want as
select a.id, a.date, a.miliseconds, sum(a.volume) as Volume
from have a
left join
grid1 b on a.id = b.id
and a.date = b.date
and a.miliseconds = floor(b.seconds)
group by a.id, a.date, a.miliseconds ;
quit;
run;
所以,找不到id和date,所以我在数据步骤中创建了它们。但是 id 不是相同的格式,我试图修复但失败了。 通过匹配秒网格线之间的毫秒数将拥有的数据集合并到想要的数据集时,我似乎遇到了错误。 我错过了什么?永远感谢您的投入! 最佳
首先,为什么要使用宏来创建一秒间隔?
do time = '09:10't to '16:50't ; output ; end ;
假设你的milliseconds
只是小数点后3位的时间,只需将floor(time)
加入相应的区间,然后总结。
proc sql ; create table want as select a.id, a.date, a.time, sum(b.volume) as Volume from grid a left join inputdataset b on a.id = b.id and a.date = b.date and a.time = floor(b.time) group by a.id, a.date, a.time ; quit ;
然后您可以 post 处理此数据集,将缺失的交易量设置为零或相应地保留之前的价格。
首先感谢大家的回答。 我想出了怎么做。可能有更简单的方法,但对我来说,现在就足够了:
data data.test;
set data.taq;
next_full_sec = int((miliseconds-1) / 1000) + 1;
run;
data data.grid;
do seconds = 1 to 86400;
output;
end;
run;
proc summary data=data.test;
by ric date time next_full_sec;
var volume;
output out=data.int (drop=_type_) sum=;
run;
proc sort data=data.test (keep=ric date) out=data.id_date nodupkey;
by ric date time;
run;
proc sql;
create table data.testseconds as
select ric, date, time, seconds
from data.id_date, data.grid
order by ric, date, time, seconds
;
quit;
data data.testout;
merge
data.testseconds (in=a rename=(fullseconds=next_full_sec))
data.int (in=b)
;
by ric date time next_full_sec;
if a;
if not b
then do;
_freq_ = 0;
volume = 0;
end;
run;
proc print noobs;
run;