根据不同的组,将缺失值替换为上一次或下一次观察

时间:2016-07-20 21:20:45

标签: sas

这是一个示例数据集。以下方案表示帐户交易历史记录列表:

  • 两位客户A和B;
  • 客户A在Bank BA和Bank UB有5个账户1,2,3,4,5;
  • 客户B在Bank WF有2个账户1,6;
  • 请注意,银行WF已向B发行了与A在银行BA中相同的帐户ID(实际上可能是真的)。​​

    data have;
     input Customer $ Account_id Bank_id $ Year;
    datalines;
    A  1  BA    .
    A  2  UB    .
    A  3  UB 2012
    A  3  UB    .
    A  4  UB    .
    A  4  UB 2013
    A  5  UB    .
    B  1  WF 2014
    B  1  WF    .
    B  6  WF    .
    ;
    

某些帐户的开放日期已丢失,但对于同一帐户,开放日期应相同。我想要做的是用其先前/后期值替换帐户的缺失日期,如果有的话;否则,保持无效。

    data want;
     input Customer $ Account_id Bank_id $ Year;
    datalines;
    A  1  BA    .
    A  2  UB    .
    A  3  UB 2012
    A  3  UB 2012
    A  4  UB 2013
    A  4  UB 2013
    A  5  UB    .
    B  1  WF 2014
    B  1  WF 2014
    B  6  WF    .
    ;

我看了一下这个例子:How to write first non-missing value to first missing observations这对我很有帮助,但我无法调整它以适用于我的案例,它有多个组。

2 个答案:

答案 0 :(得分:1)

这应该这样做:

proc sort data=have;
  by Customer
     Bank_id
     Account_id
     descending Year;
run;

data want;
  set have;
  by Customer Bank_id Account_id;
  retain year_tmp (.);

  if not last.Account_id and Year ne . then year_tmp=Year;
  else if Year = . then Year = year_tmp;
  if last.Account_id then year_tmp = .;

  drop year_tmp;
run;

我们所做的是声明一个retain变量,即一个将其值从一行保持到下一行的变量。然后使用last标志,我们将现有Year存储在该retain变量中(或将已存储的值归因于缺少的Year)。最后,我们在每个Account_id的最后一行重置retain变量。

答案 1 :(得分:0)

您可以在一个proc sql步骤中执行此操作:

proc sql ;
  create table want2 as
  select a.Customer, a.Account_id, a.Bank_id, max(a.Year,b.Year) as Year
  from have a
       left join
       (select Customer, Account_id, Bank_id, max(Year) as Year
        from have
        group by Customer, Account_id, Bank_id) b on a.Customer = b.Customer
                                                    and a.Account_id = b.Account_id
                                                    and a.Bank_id = b.Bank_id ;
quit ;