Sas 如果索引不存在,则添加索引并复制最近的值

Sas 如果索引不存在,则添加索引并复制最近的值,sas,Sas,我希望为某个id(days)的每个值(从1到该id在某个表中的最小值),按另一个变量组(date)向数据集添加记录,并为最小id记录具有的另一个变量(rate)添加相同值的记录。很可能我的解释不是很清楚,请看下面的例子 我有以下数据集myrate date days rate 02JAN1996 5 5.76 02JAN1996 10 5.81 02JAN1996 15 5.41 03JAN1996 6 5.76 03JAN1

我希望为某个id(
days
)的每个值(从1到该id在某个表中的最小值),按另一个变量组(
date
)向数据集添加记录,并为最小id记录具有的另一个变量(
rate
)添加相同值的记录。很可能我的解释不是很清楚,请看下面的例子

我有以下数据集
myrate

     date   days   rate
02JAN1996      5   5.76
02JAN1996     10   5.81
02JAN1996     15   5.41
03JAN1996      6   5.76
03JAN1996     12   5.75
03JAN1996     13   5.74
我的预期结果如下

     date   days   rate
02JAN1996      1   5.76
02JAN1996      2   5.76
02JAN1996      3   5.76
02JAN1996      4   5.76
02JAN1996      5   5.76
02JAN1996     10   5.81
02JAN1996     15   5.41
03JAN1996      1   5.76
03JAN1996      2   5.76
03JAN1996      3   5.76
03JAN1996      4   5.76
03JAN1996      5   5.76
03JAN1996      6   5.76
03JAN1996     12   5.75
03JAN1996     13   5.74
我真的不知道——我已经用一个宏解决了这个问题,它可以按组为每个组找到最小的
天数
,并输出必要的行。但我无法将这个想法转化为代码。此外,我假设有一种更简单的方法可以通过数据步骤实现这一点


编辑:我相信我可以用PROC IML解决这个问题,但我也认为这不是最有效的方法。

可以按如下方式完成:

proc sort data=myrate; by date days; run;
根据Joe的评论更新了

data want;
  set myrate;
  by date;
  if FIRST.date then do;
    do days=1 to days;
       output;
    end;
  end;
  else output;
run;

对于我的数据集,公认的答案是比下面的代码更有效。然而,在@Joe的评论之后,我试图开发我想到的PROC IML解决方案

然而,我使用的是:

proc iml;
    use myrate;
    read all var{date days rate} into mymatrix;
    unique_rows = uniqueby(mymatrix,1,1:nrow(mymatrix));
    do i=1 to nrow(unique_rows);
        if mymatrix[unique_rows[i],2] ^= 1 then do;
            currdays = mymatrix[unique_rows[i],2];
            h = J(currdays-1,1,mymatrix[unique_rows[i],1]) || (1:currdays-1)` || J(currdays-1,1,mymatrix[unique_rows[i],3]);
            mymatrix = insert(mymatrix,h,unique_rows[i]);
            unique_rows = unique_rows + currdays - 1;
        end;
    end;
    create want from mymatrix;
    append from mymatrix;
    close want;
quit;
对于具有15979017个观察值和4452个分组的数据集,此代码采用:

PROCEDURE IML used (Total process time):
real time           8:59.22
cpu time            8:59.50
当上述数据步骤执行时:

DATA statement used (Total process time):
real time           2.95 seconds
cpu time            2.22 seconds

这证明我的解决方案不好。也许有更好的方法来使用PROC IML或改进我的代码。

实际上你不必使用i,我相信你可以简单地说
do days=1到days多亏了编译器的工作原理。非常感谢,这工作得非常好。在@Joe对PROC IML的评论之后,我添加了另一个解决方案,其效率远远低于您的解决方案。老实说,我能想象的IML解决方案比暴力数据步解决方案复杂得多(更不用说像Dmitry使用的那样使用
first
更干净的数据步解决方案了)-如果有一个优雅的IML解决方案,我很想看看。嘿@Joe,再次感谢你的帮助(对帖子中的“绒毛”表示抱歉,我认为这是很好的礼仪)。我用PROC-IML解决方案添加了一个答案-这比下面提供的解决方案效率低很多。然而,对我来说,试着想出一个替代方案是一种很好的锻炼。也许有办法改进它。遗憾的是,我不认为它是优雅的,但我相信它确实发挥了作用。