使用SAS proc expand填充缺失值

时间:2016-02-04 17:25:08

标签: sas time-series

我有以下问题:

我想用proc展开填充缺失值,只需从下一个数据行中获取值。

我的数据如下:

date;index;
29.Jun09;-1693
30.Jun09;-1692
01.Jul09;-1691
02.Jul09;-1690
03.Jul09;-1689
04.Jul09;.
05.Jul09;.
06.Jul09;-1688
07.Jul09;-1687
08.Jul09;-1686
09.Jul09;-1685
10.Jul09;-1684
11.Jul09;.
12.Jul09;.
13.Jul09;-1683

正如您在某些日期所看到的那样,索引丢失了。我想实现以下目标:

date;index;
29.Jun09;-1693
30.Jun09;-1692
01.Jul09;-1691
02.Jul09;-1690
03.Jul09;-1689
04.Jul09;-1688
05.Jul09;-1688
06.Jul09;-1688
07.Jul09;-1687
08.Jul09;-1686
09.Jul09;-1685
10.Jul09;-1684
11.Jul09;-1683
12.Jul09;-1683
13.Jul09;-1683

正如您可以看到从下一行获取的缺失数据的值(11.Jul09和12Jul09从13Jul09获得值)

所以proc扩展似乎是正确的方法,我开始使用这个代码:

PROC EXPAND DATA=DUMMY
OUT=WORK.DUMMY_TS
FROM = DAY
ALIGN = BEGINNING
METHOD = STEP
OBSERVED = (BEGINNING, BEGINNING);

ID date;
CONVERT index /;
RUN;
QUIT;

这填补了空白但是从前一行和我为ALIGN设置的任何内容,OBSERVED甚至对数据降序排序我都没有实现我想要的行为。

如果你知道如何做对,那么如果你能给我一个提示就会很棒。关于proc扩展的优秀论文也是如此。

感谢您的帮助和亲切的问候 斯蒂芬

2 个答案:

答案 0 :(得分:1)

我不知道proc扩展。但显然这可以通过几个步骤完成。

读取数据集并创建一个新变量,该变量将获得 n 的值。

data have;
    set have;
    pos = _n_;
run;

按此新变量按降序对此数据集进行排序。

proc sort data=have;
    by descending pos;
run;

使用延迟或保留来填充" next" row(排序后,订单将被颠倒)。

data want;
    set have (rename=(index=index_old));
    retain index;
    if not missing(index_old) then index = index_old;
run;

如果需要,可以排序。

proc sort data=want;
    by pos;
run;

答案 1 :(得分:1)

我没有PROC EXPAND专家,但这就是我想出来的。为最大间隙运行创建LEADS(2),然后将它们合并到INDEX中。

data index;
   infile cards dsd dlm=';';
   input date:date11. index;
   format date date11.;
   cards4;
29.Jun09;-1693
30.Jun09;-1692
01.Jul09;-1691
02.Jul09;-1690
03.Jul09;-1689
04.Jul09;.
05.Jul09;.
06.Jul09;-1688
07.Jul09;-1687
08.Jul09;-1686
09.Jul09;-1685
10.Jul09;-1684
11.Jul09;.
12.Jul09;.
13.Jul09;-1683
;;;;
   run;
proc print;
   run;
PROC EXPAND DATA=index OUT=index2 method=none;
   ID date;
   convert index=lead1 / transform=(lead 1);
   CONVERT index=lead2 / transform=(lead 2);
   RUN;
   QUIT;
proc print; 
   run;
data index3;
   set index2;
   pocb = coalesce(index,lead1,lead2);
   run;
proc print;
   run;

enter image description here

修改为适用于任何合理的间隙大小。

data index;
   infile cards dsd dlm=';';
   input date:date11. index;
   format date date11.;
   cards4;
27.Jun09;
28.Jun09;
29.Jun09;-1693
30.Jun09;-1692
01.Jul09;-1691
02.Jul09;-1690
03.Jul09;-1689
04.Jul09;.
05.Jul09;.
06.Jul09;-1688
07.Jul09;-1687
08.Jul09;-1686
09.Jul09;-1685
10.Jul09;-1684
11.Jul09;.
12.Jul09;.
13.Jul09;-1683
14.Jul09;
15.Jul09;
16.Jul09;
17.Jul09;-1694
;;;;
   run;
proc print;
   run;
/* find the largest gap */
data gapsize(keep=n);
   set index;
   by index notsorted;
   if missing(index) then do;
      if first.index then n=0;
      n+1;
      if last.index then output;
      end;
   run;
proc summary data=gapsize;
   output out=maxgap(drop=_:) max(n)=maxgap;
   run;
/* Gen the convert statement for LEADs */
filename FT67F001 temp;
data _null_;
   file FT67F001;
   set maxgap;
   do i = 1 to maxgap;
      put 'Convert index=lead' i ' / transform=(lead ' i ');';
      end;
   stop;
   run;
proc expand data=index out=index2 method=none;
   id date;
   %inc ft67f001;
   run;
   quit;
data index3;
   set index2;
   pocb = coalesce(index,of lead:);
   drop lead:;
   run;
proc print;
   run;

enter image description here