【问题标题】:SAS: Marking next and previous observations with conflictsSAS:用冲突标记下一个和以前的观察
【发布时间】:2017-09-17 06:44:22
【问题描述】:

我想在 SAS 中创建假人。我的计划是,每次 AnnouncementDate ne 。我想创建一个名为 event=2 的变量,下一个也是 (event=2) 以及之前的五个观察值 1 如果前 5 次观察和公告日期后的第二天不为空,则所有这些都会被标记。 并按类别(例如按股票)

输出数据

date announcementdate event conflict
1115 . . .
2115 . . .
3115 . . .
4115 . . .
5115 . . .
6115 . 1 .
7115 . 1 .
8115 . 1 .
9115 . 1 .
10115 . 1 .
11115 1115 2 .
12115 . 2 .
13115 . .
14115 . 1 .
16115 . 1 .
17115 . 1 .
18115 . 1 .
19115 . 1 .
20115 20115 2 
21115 . 1 Y
21115 . 1 Y
22115 22115 2 Y
23115 . 2 Y
24115 . .
25115 . .

如果现在切换到下一只股票,它应该重新开始,而不是考虑之前的观察结果。

我当前的代码做了一个引导项,因为我只将事件列与 firstobs=2 合并。无论如何,这 5 倍的延迟让我感到困扰,以及之前有观察时的冲突。

data want1 ; set have;;
if announcementdate ne . then event=0;
run;

data want2; merge want1 (firstobs=2) want1 (keep=event rename= (event=event2)); 
if event2=0 then event=0; 
if event2=0 then event=event2;
run;

感谢您的任何意见!

【问题讨论】:

    标签: events sas lag lead


    【解决方案1】:

    我的方法是首先解析数据集以计算出范围是什么,使用_n_ 作为指标(而不是 id)。然后,您可以构建一个简单的起始范围并使用它来构建格式(嗯,两个,一个用于 1,一个用于 2)。

    然后,使用前瞻合并解析 那个 数据集(以获取 start 的下一个值)并查看是否存在冲突;然后使用您的逻辑为冲突标记定义另一种格式。我的例子包括这方面的逻辑;不过,它可能符合也可能不符合您的确切需求,因此您可能需要多考虑一下这个逻辑并对其进行一些修改,因为它相当具体。

    然后您只需使用_n_ 作为输入应用格式。当然,要确保原始数据集没有被排序。

    这是完整的代码。

    data have;
    input date announcementdate event_want conflict_want $;
    datalines;
    1115 . . .
    2115 . . .
    3115 . . .
    4115 . . .
    5115 . . .
    6115 . 1 .
    7115 . 1 .
    8115 . 1 .
    9115 . 1 .
    10115 . 1 .
    11115 1115 2 .
    12115 . 2 .
    13115 . . .
    14115 . 1 .
    16115 . 1 .
    17115 . 1 .
    18115 . 1 .
    19115 . 1 .
    20115 20115 2 .
    21115 . 1 Y
    21115 . 1 Y
    22115 22115 2 Y
    23115 . 2 Y
    24115 . . .
    25115 . . .
    ;;;;
    run;
    
    data for_fmt;
      set have nobs=nobs;
      length fmtname $16;
      fmtname = 'eventf';
    
      if _n_=1 then do;   *HLO='o' gives the 'other' value;
        start=.;
        end  =.;
        label = ' ';
        hlo='o';
        output;
      end;
      hlo=' ';
    
      if not missing(announcementdate) then do;
        start = max(1,_n_-5);
        end   = max(1,_n_-1);
        label='1';
        output;
        start = _n_;
        end   = min(_n_+1,nobs);
        label='2';
        output;
      end;
    run;  *now we have a dataset of the ranges - but they overlap;
    
    data for_fmt_conflicts;
    
      merge for_fmt(in=a) for_fmt(in=_in_next firstobs=2 keep=start rename=start=next_start); *look-ahead merge;
      retain new_start conflict_marker;
      if hlo='o' then do;    *again the 'other' row;
        output;
        fmtname='conflictf';
        output;
      end;
      else if end gt next_start and (_in_next) then do;   *if the next row will be a conflict, adjust the end back one and indicate where next should start;
        end = end-1;
        new_start = end+1;
        conflict_marker=1;
        output;
      end;
      else if conflict_marker=1 then do;  *if this is a conflict row type 1;
        start = new_start;
        output;
        fmtname='conflictf';
        label  ='Y';
        output;
        conflict_marker=2;
      end;
      else if conflict_marker=2 then do;  *if this is the 2s for a conflict row;
        output;
        fmtname='conflictf';
        label  ='Y';
        output;
        conflict_marker=0;
      end;
      else output;
    run;
    proc sort data=for_fmt_conflicts;  *must sort to get fmtnames grouped together;
      by fmtname start;
    run;
    proc format cntlin=for_fmt_conflicts;  *import formats;
    quit;
    
    data want;  *now apply formats;
      set have;
      event = put(_n_,eventf.);
      conflict = put(_n_,conflictf.);
    run;
    

    【讨论】:

    • 非常感谢!稍微调整了一下,但这太棒了!
    • 嗯,有一件事。我可以做任何我想做的事,但它总是给我错误:开始大于结束。
    猜你喜欢
    • 2018-10-13
    • 2021-12-15
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多