【问题标题】:Use SAS proc expand for filling missing values使用 SAS proc expand 填充缺失值
【发布时间】:2016-02-04 17:25:08
【问题描述】:

我有以下问题:

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

我的数据如下所示:

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 expand 似乎是正确的方法,我开始使用这段代码:

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 expand 的好论文也很受欢迎。

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

【问题讨论】:

    标签: sas time-series


    【解决方案1】:

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

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

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

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

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

    使用 Lag 或 Retain 从“下”行填充缺失值(排序后顺序会颠倒)。

    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;
    

    【讨论】:

    • 只是为我更基础的程序员拼写出来:这也适用于我作为一个简单的 Last Observation Carried Forward 方法 - 我只是省略了 pos 变量和排序步骤。
    【解决方案2】:

    我不是 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;
    

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

    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;
    

    【讨论】:

    • 感谢您提供详细的解决方案 - 它工作正常,并且动态引导方法很好(因为我以前没有看到它)。但是,由于 RamB 更优雅的方法,我将他的答案标记为正确。再次感谢您的帮助!斯蒂芬
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 2012-10-25
    相关资源
    最近更新 更多