2013-05-07 1 views
5

Я использую набор данные, который является чем-то вроде:Заполните пустые значения переменного с предыдущим, не пустым значением SAS 9,3

+----------+--------+-------+ 
| Variable | Level | Value | 
+----------+--------+-------+ 
| sexe  | men | 10 | 
|   | female | 20 | 
| age  | 0-20 |  5 | 
|   | 20-40 |  5 | 
|   | 40-60 | 10 | 
|   | >60 | 10 | 
+----------+--------+-------+ 

И я хотел бы выполнить «пустую» ячейку, используя предыдущий непустую ячейку, чтобы получить что-то вроде этого.

+----------+--------+-------+ 
| Variable | Level | Value | 
+----------+--------+-------+ 
| sexe  | men | 10 | 
| sexe  | female | 20 | 
| age  | 0-20 |  5 | 
| age  | 20-40 |  5 | 
| age  | 40-60 | 10 | 
| age  | >60 | 10 | 
+----------+--------+-------+ 

Я попробовал различные возможности в шаге DATA в основном с функцией LAG(). Идея состояла в том, чтобы прочитать предыдущую строку, когда ячейка была пустой и заполнить ее.

DATA test; 
    SET test; 

    IF variable = . THEN DO; 
     variable = LAG1(variable); 
    END; 
RUN; 

И я получил

+----------+--------+-------+ 
| Variable | Level | Value | 
+----------+--------+-------+ 
|   | men | 10 | 
| sexe  | female | 20 | 
|   | 0-20 |  5 | 
| age  | 20-40 |  5 | 
|   | 40-60 | 10 | 
|   | >60 | 10 | 
+----------+--------+-------+ 

Проблема была хорошая строка не всегда только одна строка верхней. Но я не понимаю, почему SAS пуст в первой и третьей строках. Он не должен был изменять эту строку, потому что я сказал «If variable =.». Я знаю, как это сделать на Python или в R с некоторыми циклами, но я не нашел хорошего решения в SAS.

Я попытался поместить строку внутри переменной с "CALL SYMPUT", а также с "", но это тоже не сработало.

Должен быть простой и элегантный способ сделать это. Есть идеи?

+0

Полезный вопрос. Большое спасибо. – stan

ответ

18

Вы не можете использовать LAG внутри IF и получить этот результат - LAG на самом деле не работает так, как вы думаете. СОХРАНИТЬ правильный путь, я бы сказал:

DATA test; 
    SET test; 
    retain _variable; 
    if not missing(variable) then _variable=variable; 
    else variable=_variable; 
    drop _variable; 
RUN; 

Лаг фактически не перейти к предыдущей записи и получить его значение; то, что он делает, настроен на очередь, и каждый раз, когда LAG называется, он снимает запись с фронта и добавляет запись назад. Это означает, что если LAG находится внутри условного блока, он не будет выполняться для ложного условия, и вы не получите свою очередь. Вы можете использовать функции IFN и IFC, которые оценивают как истинные, так и ложные условия независимо от логического, но в этом случае RETAIN, вероятно, проще.

+0

Работайте отлично, и объяснения очень ясны! Большое спасибо Джо! Это второй раз, когда вы мне помогаете и так быстро. Как вы это делаете? Отслеживание всех вопросов по RSS? – jomuller

+0

RSS на самом деле довольно медленно обновлять (но, да, в некоторых случаях); вы только что спросили об этом вскоре после того, как я ответил на другой вопрос :) – Joe

+0

Полезный ответ. Большое спасибо. – stan