首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >做循环+滞后函数?

做循环+滞后函数?
EN

Stack Overflow用户
提问于 2015-02-10 03:33:44
回答 2查看 1.1K关注 0票数 1

这是我的第一篇帖子,所以如果我不够清楚,请告诉我。这是我想做的-这是我的数据集。我的方法是一个滞后的do循环,但结果是垃圾。

代码语言:javascript
复制
data a;
input @1 obs @4 mindate mmddyy10. @15 maxdate mmddyy10.;
format mindate maxdate date9.;
datalines;
1   01/02/2013 01/05/2013
2   01/02/2013 01/05/2013
3   01/02/2013 01/05/2013
4   01/03/2013 01/06/2013
5   02/02/2013 02/08/2013
6   02/02/2013 02/08/2013
7   02/02/2013 02/08/2013
8   03/10/2013 03/11/2013
9   04/02/2013 04/22/2013
10  04/10/2013 04/22/2013
11  05/04/2013 05/07/2013
12  06/10/2013 06/20/2013
;
run;

现在,我正在尝试根据以下逻辑生成一个新列--“替换”:

  1. 如果记录的最小日期发生在滞后的最大值之前,则不能替换它。如果不能替换,跳过(SO-2,3,4不能替换1,但5可以)。
  2. 否则..。如果mindate小于30天,则替换= Y。如果不是,则替换= N。一旦记录替换另一个记录(因此,在这种情况下,5确实替换了1,因为02/02/2013比01/05/2013 <30,因此不能重复作为另一记录的替换。但是,如果上面的一个记录是N,那么对于其他记录,它仍然可以是Y。因为这两个组合都是"Y",所以8现在是相对于4,但是因为它的mindate >30相对于4的最大值,所以它是一个N,但是,然后根据它来进行评估。
  3. 等等..。

我应该在100条记录数据集中,这意味着第100条记录在技术上可以取代第1条,所以我一直在循环中尝试延迟。任何提示/帮助都是非常感谢的!预期产出:

代码语言:javascript
复制
                      obs      mindate      maxdate    Replacement

                        1    02JAN2013    05JAN2013
                        2    02JAN2013    05JAN2013
                        3    02JAN2013    05JAN2013
                        4    03JAN2013    06JAN2013
                        5    02FEB2013    08FEB2013         Y
                        6    02FEB2013    08FEB2013         Y
                        7    02FEB2013    08FEB2013         Y
                        8    10MAR2013    11MAR2013         Y
                        9    02APR2013    22APR2013         Y
                       10    10APR2013    22APR2013         N
                       11    04MAY2013    07MAY2013         Y
                       12    10JUN2013    20JUN2013         Y
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-02-10 21:37:18

我认为这是正确的,如果提问者是错误的替换=Y= obs = 12。

代码语言:javascript
复制
/*Get number of obs so we can build a temporary array to hold the dataset*/
data _null_;
    set have nobs= nobs;
    call symput("nobs",nobs);
    stop;
run;

data want;
    /*Load the dataset into a temporary array*/
    array dates[2,&NOBS] _temporary_;
    if _n_ = 1 then do _n_ = 1 by 1 until(eof);
        set have end = eof;
        dates[1,_n_] = maxdate;
        dates[2,_n_] = 0;
    end;

    set have;

    length replacement $1;

    replacement = 'N';
    do i = 1 to _n_ - 1 until(replacement = 'Y');
        if dates[2,i] = 0 and 0 <= mindate - dates[1,i] <= 30 then do;
            replacement = 'Y';
            dates[2,i] = _n_;
            replaces = i;
        end;
    end;
    drop i; 
run;

如果您愿意,可以使用散列对象+散列迭代器而不是临时数组。我还添加了一个额外的变量replaces,以显示每一行替换的前一行。

票数 1
EN

Stack Overflow用户

发布于 2015-02-10 20:45:20

下面是使用SQL和哈希表的解决方案。这并不是最优的,但它是第一次出现在脑海中的方法。

代码语言:javascript
复制
/* Join the input with its self */
proc sql;
    create table b as
    select 
        a1.obs, 
        a2.obs as obs2
    from a as a1
    inner join a as a2
        /* Set the replacement criteria */
        on a1.maxdate < a2.mindate <= a1.maxdate + 30
    order by a2.obs, a1.obs;
quit;
/* Create a mapping for replacements */
data c;
    set b;
    /* Create two empty hash tables so we can look up the used observations */
    if _N_ = 1 then do;
        declare hash h();
        h.definekey("obs");
        h.definedone(); 
        declare hash h2();
        h2.definekey("obs2");
        h2.definedone();
    end;
    /* Check if we've already used this observation as a replacement */
    if h2.find() then do;
        /* Check if we've already replaced his observation  */
        if h.find() then do;
            /* Add the observations to the hash table and output */
            h2.add();
            h.add();
            output;
        end;
    end;
run;
/* Combine the replacement map with the original data */
proc sql;
    select 
        a.*, 
        ifc(c.obs, "Y", "N") as Replace, 
        c.obs as Replaces
    from a
    left join c
        on a.obs = c.obs2
    order by a.obs;
quit;

有几种方法可以简化这一点:

  • 日期可以通过第一个proc sql获得。
  • 可以组合if语句
  • 在数据步骤中,可以用一些额外的逻辑来替换最后的联接。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28423622

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档