在SAS

时间:2016-02-17 11:17:33

标签: merge window sas subquery output

我正在尝试合并并输出SAS中的一些数据集。这个想法非常简单,

我的数据如下:

Data1(目标数据)

RIC       date           
VOD     03/02/2014         
BATS    03/02/2014         
...       ...             

Data2(样本数据)

RIC       date           price
VOD     01/02/2014         50
VOD     03/02/2014         57
VOD     05/02/2014         64
VOD     06/02/2014         58
VOD     08/02/2014         64
VOD     10/02/2014         57
...       ...             ...
BATS    01/02/2014         70
BATS    03/02/2014         58
BATS    05/02/2014         67
BATS    06/02/2014         55
...       ...             ...

现在我需要将Data1与Data2合并,仅将目标数据与(-1,+ 1)交易日窗口保持。最终输出将如下所示:

RIC  Trading_day_window     date           price
VOD         -1            01/02/2014         50
VOD          0            03/02/2014         57
VOD         +1            05/02/2014         64
BATS        -1            01/02/2014         70
BATS         0            03/02/2014         58
BATS        +1            05/02/2014         67

我知道我必须先在这里使用merge。但是如何仅将目标数据保留在(-1,+ 1)交易日窗口中?

我想我可能会在这里使用subquery。 谁能帮我吗 ?谢谢!

4 个答案:

答案 0 :(得分:1)

使用双DOW循环。在第一个中找到日期匹配的记录。在第二个输出你想要的记录。

以下是您的样本数据,已正确排序。

data data1 ;
  input RIC $ date ;
  informat date ddmmyy10.;
  format date yymmdd10.;
cards;
BATS 03/02/2014
VOD 03/02/2014
;;;;
data data2;
  input RIC $ date price ;
  informat date ddmmyy10.;
  format date yymmdd10.;
cards;
BATS 01/02/2014 70
BATS 03/02/2014 58
BATS 05/02/2014 67
BATS 06/02/2014 55
VOD 01/02/2014 50
VOD 03/02/2014 57
VOD 05/02/2014 64
VOD 06/02/2014 58
VOD 08/02/2014 64
VOD 10/02/2014 57
;;;;

现在只需通过RIC和DATE合并,找到匹配的记录。

data want ;
  do trading_day=1 by 1 until (last.ric);
    merge data1 (in=in1) data2;
    by ric date;
    if in1 then baseday = trading_day;
  end;
  do trading_day=1 by 1 until (last.ric);
    merge data1 (in=in1) data2;
    by ric date;
    if baseday -1 <= trading_day <= baseday+1 then do;
         trading_day_window = trading_day-baseday;
         output;
    end;
  end;
run;
proc print; run;

enter image description here

答案 1 :(得分:0)

您可以在数据步骤中使用retain语句。

答案 2 :(得分:0)

简单的proc sql语句可以使用联接中的between语句执行此操作。我已编码+/- 2天,因为您的示例数据中似乎就是这种情况,您显然可以对此进行调整,以符合您用于计算交易窗口的任何规则。

data data1;
input RIC $ date :ddmmyy10.;
format date date9.;
datalines; 
VOD     03/02/2014
BATS    03/02/2014
;
run;

data data2;
input RIC $ date :ddmmyy10. price;
format date date9.;
datalines;
VOD     01/02/2014         50
VOD     03/02/2014         57
VOD     05/02/2014         64
VOD     06/02/2014         58
VOD     08/02/2014         64
VOD     10/02/2014         57
BATS    01/02/2014         70
BATS    03/02/2014         58
BATS    05/02/2014         67
BATS    06/02/2014         55
;
run;

proc sql;
create table want 
as select 
    b.ric,
    b.date-a.date as trading_day_window,
    b.date,
    b.price
from data1 as a
     inner join
     data2 as b
     on a.ric=b.ric 
     and b.date between a.date-2 and a.date+2;
quit;

答案 3 :(得分:0)

你在这里得到了一些好的答案,所以你必须玩它才能选择效率最高的。

我怀疑你的数据1非常小。如果是,那么我认为这将是相当高效的代码,因为它避免了排序和潜在的sql优化器malarchy。否则,SQL解决方案似乎对我来说最实用。

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

data want(drop=date_ref ric_ref);
set data2;
   do   i = 1 to &obscount.;
    set data1 (rename=(date=date_ref ric=ric_ref)) point=i;
    trading_day_window = (abs(date-date_ref)-1)*sign(date-date_ref);
    if ric=ric_ref
        and -1 <= trading_day_window <= 1
    then output;
   end;
run;