2016-02-04 143 views
0

我有以下问题:使用SAS proc扩展填充缺失值

我想用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,观测或甚至对数据进行排序降序我没有达到我想要的行为。

如果你知道如何做正确的话,如果你能给我一个提示就太好了。关于proc扩展的良好论文也同样适用。

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

回答

1

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

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

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

将此数据集按此降序排列,按此新变量排序。

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

使用滞后或保留来填充“下一个”行中的缺失值(排序后,顺序将颠倒)。

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

我不是PROC EXPAND的专家,但这是我想出的。为最大差距运行(2)创建LEADS,然后将它们合并到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

+0

感谢您详细的解决方案 - 它工作正常,动态铅的方法是很好的(因为我没有看到过它)。但是,由于RamB更优雅的方法,我将他的答案标记为正确。再次感谢你的帮助!斯蒂芬 –