2016-02-04 196 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更優雅的方法,我將他的答案標記爲正確。再次感謝你的幫助!斯蒂芬 –