【问题标题】:In SAS how to print leading and lagging observations在SAS中如何打印领先和落后的观察
【发布时间】:2018-12-02 19:24:16
【问题描述】:

我正在寻找一种根据标志变量打印当前、领先和滞后观察的方法。如果一个观察被标记,我想打印那个观察,加上它的滞后行和前导行。

有:

    ID        VAR1        VAR2        Flag
    --------------------------------------      
    ID1        1           15           .
    ID1        2           14           1
    ID1        3           13           .
    ID1        4           12           .
    ID2        5           11           .
    ID2        6           10           .
    ID2        7            9           1
    ID2        8            8           .   
    ID2        9            7           . 
    ID3        10           6           .
    ID3        11           5           1
    ID3        12           4           .
    ID3        13           3           .
    ID3        14           2           1
    ID3        15           1           .

想要:

    ID        VAR1        VAR2        Flag
    --------------------------------------      
    ID1        1           15           .
    ID1        2           14           1
    ID1        3           13           .
    ID2        6           10           .
    ID2        7            9           1
    ID2        8            8           .  
    ID3        10           6           .
    ID3        11           5           1
    ID3        12           4           .
    ID3        13           3           .
    ID3        14           2           1
    ID3        15           1           .

我已经尝试过Proc Expand 函数,但由于此过程无法处理缺失值,因此不适用于我的工作案例。

另一种方法是将数据集排序为所需的顺序,然后创建一个变量,按顺序对每一行进行编号——根据标志打印当前行 +1,-1。

是否有更直接的方法可以根据标志获得由当前行、滞后行和前导行组成的数据集?

【问题讨论】:

    标签: sas


    【解决方案1】:

    使用 LAG() 函数很容易找到 FLAG 的先前值。找到下一个值有点困难。这是一个方法。

    data want ;
      set have end=eof;
      by id ;
      if not eof then set have(keep=flag rename=(flag=lead_flag) firstobs=2);
      lag_flag=lag(flag);
      if first.id then call missing(lag_flag);
      if last.id then call missing(lead_flag);
      if flag or lead_flag or lag_flag ;
    run;
    

    【讨论】:

      【解决方案2】:

      您可以将 var1+1 和 var-1 用于 flag = 。如下图。

           proc sql;
      create table want as 
      select distinct a.* from 
      (select * from have)a
      inner join 
      (select * from have
      where flag = 1 )b
      on a.var1 = b.var1
      or a.var1 = b.var1-1
      or a.var1 = b.var1 +1;
      

      【讨论】:

        【解决方案3】:

        更一般的情况是

        • 在每个组内报告满足支点条件的每一行以及之前的 p 行和之后的 q

        pq 将对应于 lag-sizelead-size 的概念。散列对象可以跟踪应该输出的行的组内序列号。双 DOW 技术用于对组进行度量(计算输出的 seq 数),然后评估组中每个项目的度量。

        例如:

        data have;
          do id = 'A', 'B', 'C', 'D';
            do seq = 1 to 36;
               rowid + 1;
        
               x = seq;
               if id = 'D' then x = floor(12*ranuni(123));
        
               flag = mod(x,7);
               output;
            end;
          end;
        run;
        
        
        %let lagsize = 2;
        %let leadsize = 3;
        
        data want;
          if _n_ = 1 then do;
            declare hash marks();
            retain __n .;
            marks.defineKey('__n');
            marks.defineData('__n');
            marks.defineDone();
          end;
        
          marks.clear();
          do __n = 1 by 1 until(last.id);
            set have;
            by id;
            if 
              flag=0 /* fulcrum criteria checked for each row in group */
            then do;
              * computation is "store sequence number that would fall in the lag lead 'about' space";
              _n_ = __n;
              do __n = _n_ - &lagsize to _n_ + &leadsize;
                marks.replace();
              end;
              __n = _n_;
            end;
          end;
        
          do __n = 1 to __n;
            set have;
            if marks.check()=0 then output; * evaluate for each row in group;
          end;
        run;
        

        该技术可以扩展到基于不同支点条件想要不同“大约”尺寸的情况。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-02-26
          • 1970-01-01
          • 1970-01-01
          • 2013-04-28
          • 2022-06-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多