使用SAS满足数值条件时,更改先前和后记录中的值

时间:2014-04-28 22:28:33

标签: sas

data have;
input patient level timepoint;
datalines;
1   0   1
1   0   2
1   0   3
1   3   4
1   0   5
1   0   6
2   0   1
2   4   2
2   0   3
2   3   4
2   0   5
2   0   6
2   0   7
2   2   8
2   0   9
2   0   10
3   3   1
3   0   2
3   0   3
4   0   1
4   0   2
4   0   3
4   0   4
4   1   5
4   0   6
4   0   7
4   0   8
4   0   9
4   0   10

;;
proc print; run;

/ * 条件1:如果有一个非零数值,在级别中,按患者的时间点排序,则将该级别设置为紧接该时间点之前的记录;并为下一个先前时间点设置level = 1.5;对于此时间点之后的记录,将级别设置为2.5;并为下一个帖子记录设置级别为1.5。按时间点的级别应该看起来像...... 1.5,2.5,非零数值,2.5,1.5 ......(注意:......保持为0)。

条件2:如果有两个或多个非零数值,在级别中,按患者的时间点排序,找到FIRST非零数值,并将级别设置为2.5,以便在此之前的记录中时间点;并将下一个时间点的水平设定为1.5;然后找到最后的非零数值记录,为最后一个非零数值后立即记录设置级别为2.5,并为下一个后记录设置级别为1.5;对于第一个和最后一个非零数值之间的记录,将所有零值(即level = 0)设置为level = 2.5;按时间点的级别应如下所示:... 1.5,2.5,FIRST非零数值,2.5,非零数值,2.5,最后非零数值,2.5,1.5 .... * /

我使用 N -1, N -2, N +1, N +2,数组/执行循环(我首先想到的是为此使用多个数组,这样我就可以使用i = index来转到之前的i-1 / i + 1或i-2/1 + 2记录,但是很难掌握如何编码它的概念。所有这一切都必须由患者完成,因此可能存在在第一个非零之前只有一个记录而不是两个记录的情况。对于后期记录也是如此。我搜索了所有不同类型的示例和帮助,但没有一个可以帮助我的需求。提前感谢您的帮助。

这就是我希望数据的样子:

    data want;
    input patient level timepoint;
datalines;
1   0   1
1   1.5 2
1   2.5 3
1   3   4
1   2.5 5
1   1.5 6
2   2.5 1
2   4   2
2   2.5 3
2   3   4
2   2.5 5
2   2.5 6
2   2.5 7
2   2   8
2   2.5 9
2   1.5 10
3   3   1
3   2.5 2
3   1.5 3
4   0   1
4   0   2
4   1.5 3
4   2.5 4
4   1   5
4   2.5 6
4   1.5 7
4   0   8
4   0   9
4   0   10

;;
proc print; run;

1 个答案:

答案 0 :(得分:1)

我通过首先找到第一个和最后一个非零水平的时间点来解决这个问题。然后我将它们合并到原始集合中,并根据您提到的规则更改级别。

proc sort data = have;
    by patient timepoint;
run;

data have2;
    retain first 0 last 0;
    set have;
    by patient timepoint;
    if level ne 0 and first = 0 then first = timepoint;
    if level ne 0 then last = timepoint;
    if last.patient then do;
        output;
        first = 0;
        last = 0;
    end;
    keep patient first last;
run;

proc sort data=have2;
    by patient;
run;

data merged;
    merge have have2;
    by patient;
    if level = 0 then do;
        if first-timepoint = 1 then level = 2.5;
        if first-timepoint = 2 then level = 1.5;
        if last-timepoint = -1 then level = 2.5;
        if last-timepoint = -2 then level = 1.5;
        if first < timepoint < last then level = 2.5;
    end;
    drop first last;
run;