Замена пропущенных значений ближайшим непропущенным значением - PullRequest
2 голосов
/ 27 сентября 2019

У меня есть набор данных с некоторыми пропущенными значениями, и я хотел бы заменить эти пропущенные значения следующим не пропущенным значением ИЛИ, если значение встречается в последней переменной, то на предыдущее значение.

Например, у меня есть данные:

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 ]

1 голос
/ 27 сентября 2019

Если я понимаю, значение из следующей строки будет занесено в текущую строку, только если отсутствует var1, в противном случае отсутствующие значения в текущей строке являются распространением значения влево (даже когда само это значениеот предыдущего слева направо распространения).

Получение строки next , также известное как lead , может быть выполнено с помощью возвратного слияния 1: 1 с однимсамо продвигается на одну строку с помощью опции firstobs=.

data have; input
x& $8. var1 var2 var3 var4; datalines;
e1   1    2    3    4
e2   .    .    5    7
e3   5    8    .    .
e4   2    3    1    9
run;

data want;
  * reflexive 1:1 merge;
  merge
    have
    have(firstobs=2 keep=var1 rename=var1=lead1)
  ;

  if missing(var1) then var1=lead1;

  array v var1-var4;

  do _i_ = 2 to dim(v);
    if missing(v(_i_)) then v(_i_)=v(_i_-1);
  end;

  drop lead:;
run;
0 голосов
/ 27 сентября 2019

Интуитивно понятный подход заключается в том, чтобы просто проходить по массиву, пока не встретится пропущенное значение.Затем переберите оставшуюся часть массива в поисках следующего не пропущенного значения.Если пропущенное значение встречается в конце (точнее: без пропущенных значений в оставшейся части массива), у нас все еще будут отсутствующие значения в конце этих циклов.

Затем мы можем выполнить ту же процедуру в обратном порядке, начиная с конца массива и продвигаясь к началу.

Я бы не стал использовать _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;
...