Merge 在SAS中合并并输出所选数据

Merge 在SAS中合并并输出所选数据,merge,window,sas,subquery,output,Merge,Window,Sas,Subquery,Output,我正在尝试在SAS中合并和输出一些数据集。这个想法很简单, 我的数据如下所示: 数据1(目标数据) 数据2(样本数据) 现在我需要将数据1与数据2合并,并且只保留带有(-1,+1)交易日窗口的目标数据。最终输出如下所示: RIC Trading_day_window date price VOD -1 01/02/2014 50 VOD 0 03/02/2014

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

我的数据如下所示:

数据1(目标数据)

数据2(样本数据)

现在我需要将数据1与数据2合并,并且只保留带有(-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)个交易日窗口的目标数据?

我想我可以在这里使用
子查询

有人能帮我吗?谢谢

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

一个简单的
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;

使用双道循环。在第一个中,找到日期匹配的记录。在第二个窗口中,输出所需的记录

这是您的样本数据,已正确排序

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和日期合并并找到匹配的记录

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;
需要数据;
交易日=1乘1直到(last.ric);
合并数据1(in=in1)数据2;
截止日期;
如果为1,则基准日=交易日;
结束;
交易日=1乘1直到(last.ric);
合并数据1(in=in1)数据2;
截止日期;

如果baseday-1您在这里有一些好的答案,那么您必须使用它来选择最有效的答案

我怀疑你的数据很小。如果是,那么我认为这将是非常有效的代码,因为它避免了排序和潜在的sql优化器混乱。否则,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;
procsqlnoprint;
选择计数(*)
进入:障碍
从数据1;
退出
所需数据(drop=日期参考ric参考);
设置数据2;
i=1到&obscount。;
设置数据1(重命名=(日期=日期参考ric=ric参考))点=i;
交易日窗口=(abs(日期参考)-1)*签名(日期参考);
如果ric=ric_ref

和-1谢谢,我以前用过
retain
,但是你能给我更多的信息吗?谢谢
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;
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;