SAS:按ID重复最后一个值

SAS:按ID重复最后一个值,sas,retain,Sas,Retain,我有这个数据库: data temp; input ID date type ; datalines; 1 10/11/2006 1 1 10/12/2006 2 1 15/01/2007 2 1 20/01/2007 3 2 10/08/2008 1 2 11/09/2008 1 2 17/10/2008 1 2 12/11/2008 2 2

我有这个数据库:

data temp;
input ID date type ;
  datalines;
 1 10/11/2006   1      
 1 10/12/2006   2      
 1 15/01/2007   2      
 1 20/01/2007   3    
 2 10/08/2008   1        
 2 11/09/2008   1        
 2 17/10/2008   1        
 2 12/11/2008   2    
 2 10/12/2008   3       
 ;
我想创建一个新列,在其中按ID重复上次日期:

data temp;
input ID date type  last_date;
  datalines;
 1 10/11/2006   1        20/01/2007
 1 10/12/2006   2        20/01/2007
 1 15/01/2007   2        20/01/2007
 1 20/01/2007   3        20/01/2007
 2 10/08/2008   1        10/12/2008
 2 11/09/2008   1        10/12/2008
 2 17/10/2008   1        10/12/2008
 2 12/11/2008   2        10/12/2008
 2 10/12/2008   3        10/12/2008
 ;
我尝试过此代码,但不起作用:

  data temp;
  set temp;
  IF last.ID then last_date= .;
  RETAIN last_date;
  if   missing(last_date) then last_date= date;
  run;

提前感谢您的帮助

首先,除非在BY语句中包含变量ID,否则不会在数据步骤中创建First.ID和LAST.ID变量

其次,要将最后一个日期附加到每个观测值,您需要对数据进行两次处理。您当前的代码(如果添加了BY语句)将只为BY组最后一次观察时的LAST_DATE赋值

实现这一点的一种方法是在每个按组中按日期降序对数据重新排序,然后您可以使用by ID和FIRST.ID并保留

proc sort data=have;
   by id descending date;
run;
data want;
   set have;
   by id descending date;
   if first.id then last_date=date;
   retain last_date;
   format last_date ddmmyy10.;
run;
这里有一种使用原始排序顺序的方法,使用所谓的双道循环。通过将SET/By语句放在DO循环中,您可以在数据步骤的一次传递中读取组的所有观察值。然后添加第二个DO循环以按组重新处理该循环,并使用第一个循环中计算的信息写出观察结果

data want;
do until (last.id);
  set have;
  by id;
end;
last_date=date ;
format last_date ddmmyy10.;
do until (last.id);
  set have;
  by id; 
  output;
end;
run;

首先,除非在BY语句中包含变量ID,否则不会在数据步骤中创建First.ID和LAST.ID变量

其次,要将最后一个日期附加到每个观测值,您需要对数据进行两次处理。您当前的代码(如果添加了BY语句)将只为BY组最后一次观察时的LAST_DATE赋值

实现这一点的一种方法是在每个按组中按日期降序对数据重新排序,然后您可以使用by ID和FIRST.ID并保留

proc sort data=have;
   by id descending date;
run;
data want;
   set have;
   by id descending date;
   if first.id then last_date=date;
   retain last_date;
   format last_date ddmmyy10.;
run;
这里有一种使用原始排序顺序的方法,使用所谓的双道循环。通过将SET/By语句放在DO循环中,您可以在数据步骤的一次传递中读取组的所有观察值。然后添加第二个DO循环以按组重新处理该循环,并使用第一个循环中计算的信息写出观察结果

data want;
do until (last.id);
  set have;
  by id;
end;
last_date=date ;
format last_date ddmmyy10.;
do until (last.id);
  set have;
  by id; 
  output;
end;
run;
其他两种方式是:

  • Proc SQL
    加入子选择,或
  • Proc意味着
    +
    数据/合并
SQL

 proc sql;
   create table want as
   select have.*, id_group.max_date as last_date format=ddmmyy10.
   from
     have
   join 
     ( select id, max(date) as max_date
       from have
       group by id
     ) as id_group
   on
     have.id = id_group.id
   ; 
表示

proc means noprint data=have;
  by id;
  var date;
  output out=maxdates(keep=id last_date) max(date)=last_date;
run;

data want;
  merge have maxdates;
  by id;
run;
其他两种方式是:

  • Proc SQL
    加入子选择,或
  • Proc意味着
    +
    数据/合并
SQL

 proc sql;
   create table want as
   select have.*, id_group.max_date as last_date format=ddmmyy10.
   from
     have
   join 
     ( select id, max(date) as max_date
       from have
       group by id
     ) as id_group
   on
     have.id = id_group.id
   ; 
表示

proc means noprint data=have;
  by id;
  var date;
  output out=maxdates(keep=id last_date) max(date)=last_date;
run;

data want;
  merge have maxdates;
  by id;
run;