2016-02-17 2 views
1

Я пытаюсь объединить и вывести некоторый набор данных в SAS. Идея очень проста,Слияние и вывод выбранных данных в SAS

Мои данные выглядит следующим образом:

Data1 (Target Data)

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 здесь. Может ли кто-нибудь помочь мне? Благодаря !

ответ

0

Вы можете использовать оператор retain на своем шаге данных.

+0

спасибо, я использовал 'удержание' раньше, но можете ли вы дать мне больше информации? спасибо – FlyUFalcon

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; 
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

+0

Дорогой Том, это очень умный метод !!! Огромное спасибо !!!! – FlyUFalcon

0

У вас есть некоторые хорошие ответы здесь, так что вам придется играть с ним, чтобы выбрать наиболее эффективный.

Я подозреваю, что ваши данные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;