用最接近的非缺失值替换缺失值

时间:2019-09-27 10:25:41

标签: sas

我有一个缺少一些值的数据集,我想用下面的非缺失值替换那些缺失的值,或者如果该值出现在最后一个变量中,则替换为先前的值。

例如,我拥有的数据

x   var1 var2 var3 var4
e1   1    2    3    4
e2   .    .    5    7
e3   5    8    .    .
e4   2    3    1    9

Eg of data that I want:

x   var1 var2 var3 var4
e1   1    2    3    4
e2   **5****5**    5    7
e3   5    8    **8**    **8**
e4   2    3    1    9

我尝试了以下代码:

set have;
array t(*) var1--var4;
do _n_=1 to dim(t);
if t(_n_)=. then t(_n_)=coalesce(of t(*));
end;
run;```

However, this only replaces the missing value with the following one ie, if the missing value occurs in the var4 then it takes the value from var1 of that row (e3) instead of var2 from row e3.

2 个答案:

答案 0 :(得分:1)

据我了解,只有缺少var1时,下一行的值才会被带到当前行,否则当前行中的丢失值就是该值在左侧的传播(即使值本身是从先前的左传播到右传播)。

下一个行检索,也称为 lead ,可以使用1:1自反合并,并使用选项{{11 }。

firstobs=

答案 1 :(得分:0)

一种直观的方法是简单地遍历数组直到遇到缺失值。然后遍历数组的其余部分,寻找下一个非缺失值。如果缺失值出现在末尾(更确切地说:在数组的其余部分中没有非缺失值),则在这些循环的末尾仍然会有缺失值。

然后,我们可以反向执行相同的过程,从数组的末尾开始,一直到起点。

我避免使用_n_作为变量名,因为它是SAS中的自动变量。

data want;
    set have;
    array t(*) var1--var4;
    /*  Following value*/
    do n=1 to dim(t)-1;
        inner=n;
        do while (t(n)=. and inner lt dim(t));
            t(n)=t(inner+1);
            inner+1;
        end;
    end;
    /*  If there was no following value, we still have missing values, and finds previous instead*/
    do n=dim(t) to 2 by -1;
        inner=n;
        do while (t(n)=. and inner gt 0);
            t(n)=t(inner-1);
            inner+ (-1);
        end;
    end;
    drop n inner;
run;