【问题标题】:Merge and output selected data in SAS在 SAS 中合并和输出选定的数据
【发布时间】:2016-02-17 11:17:33
【问题描述】:

我正在尝试在 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) 个交易日窗口的 Target 数据?

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

【问题讨论】:

    标签: merge window sas subquery output


    【解决方案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;
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 谢谢,我以前用过retain,但你能给我更多的信息吗?谢谢
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        你在这里得到了一些很好的答案,所以你必须使用它来选择最有效的。

        我怀疑您的 data1 非常小。如果是这样,那么我认为这将是非常有效的代码,因为它避免了排序和潜在的 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;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-04
          • 1970-01-01
          • 2022-12-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多