Заполните, начиная с того момента, когда условие выполнено, и до другого условия в SAS - PullRequest
0 голосов
/ 16 октября 2018

Я застрял, чтобы решить эту проблему в SAS.Вероятно, это не так сложно, но я попробовал вещи с циклами retain и re, которые не работали.

В основном каждый идентификатор имеет данные на каждую дату.На основании других переменных они могут войти в состояние снижения (шаг переменной> 0), и иногда они будут соответствовать конечному условию1.Если условие 1 = 1 выполнено, мне нужно пометить «эпизод», начинающийся с начала уменьшения.

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

    ID  date    step    condition1  flag
    z   1       0       .   
    z   2       0       .   
    z   3       0       .   
    z   4       1       .           TRUE
    z   5       2       .           TRUE
    z   6       2       .           TRUE
    z   7       3       .           TRUE
    z   8       4       .           TRUE
    z   10      4       .           TRUE
    z   11      4       1           TRUE
    z   12      4       .   
    z   13      4       .   
    z   14      0       .   
    z   15      0       .   
    z   16      0       .   
    z   17      1       .   
    z   18      2       .   
    z   19      2       .   
    z   20      0       .   
    z   21      0       .   

edit: таблица с переменной, используемой для определения уменьшения

ID  date    quantity    step    condition1  flag
z   1       90          0       .   
z   2       90          0       .   
z   3       100         0       .   
z   4       90          1       .           TRUE
z   5       80          2       .           TRUE
z   6       80          2       .           TRUE
z   7       50          3       .           TRUE
z   8       0           4       .           TRUE
z   10      0           4       .           TRUE
z   11      0           4       1           TRUE
z   12      0           4       .   
z   13      0           4       .   
z   14      40          0       .   
z   15      50          0       .   
z   16      60          0       .   
z   17      40          1       .   
z   18      40          2       .   
z   19      30          2       .   
z   20      60          0       .   
z   21      60          0       .   

Я пытался отсортировать ее по ID инисходящая дата, которая, кажется, имеет смысл.

proc sort data= have; 
by id descending  date ;
run;

Вот одна из многих вещей, которые я пробовал - но она застряла;(Отредактировано)

DATA want  ;
SET have;
if four=1 then do;
 do until (step<1) ; flag=1;  output;
 end;
end;
run;

Любая помощь приветствуется.Мне, наверное, просто нужен намек в правильном направлении.Спасибо

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Внутри групповой обработки, требующей оценки по набору строк, которая должна применяться к одним и тем же строкам, можно выполнить с использованием шаблона кодирования «последовательный DOW».Ваши данные могут иметь несколько сегментов в группе, поэтому все это будет вложено во внешний цикл do.

Пример

Ваши ограничения на комбинации шагов и условий не полностью объяснены, поэтому примерлогика может охватывать не все случаи.

В этом примере index_first_after_last_zero отслеживает начало ряда строк с step > 0 и заканчивается condition1 = 1

data want;
  do until (last.id);

    segment = sum(segment,1);  * <------ helper for understanding logic;

    * 'measuring loop' that computes or tracks some multi-row condition within group;
    do index = 1 by 1 until (condition1 or last.id);
      set have;       * <------ SET inside loop;
      by id date;     * <------ BY for last.id and ensures dates are ordered;

      * track start of last run of non-zero steps;
      if step=0 then 
        index_first_after_last_zero = index + 1;
    end;

    * track end of run flag;
    segment_end_condition = condition1;

    * end of loop value is fixed at start of loop and thus not affected by automatic BY 1 increment;
    * thus 1 to index iterates same number of rows as the 'measuring' loop;
    do index = 1 to index;

      set have;     * <------ second SET use a separate file buffer than first SET;

      * apply flag value -- missing for pre-run rows, and end of run flag to run rows;
      if index < index_first_after_last_zero 
        then flag = .;
        else flag = segment_end_condition;

      OUTPUT;
    end;

  end;
run;
0 голосов
/ 16 октября 2018

Вы не можете использовать do until таким образом на шаге данных - он будет повторяться, но не будет читать никаких дополнительных наблюдений из набора входных данных.

Я думаю, что ключевая идея, которую вынеобходимо сохранить отдельные переменные состояния, чтобы запомнить то, что вы уже видели:

proc sort data=have; 
  by id date;
run;

data want;
  retain episode_started episode_finished;
  set have;
  by id;
  if first.id then do;
    episode_started = 0;
    episode_finished = 0;
  end;
  if step > 0 then episode_started = 1;
  if episode_started and not episode_finished then flag = 'TRUE';
  output;
  if condition1 then episode_finished = 1;
run;

Я не проверял это, но оно должно быть близко.Вы можете просмотреть два добавленных флага в выходном наборе данных, чтобы понять, когда и как они устанавливаются.Вы можете достичь того же, используя одну переменную состояния с более чем двумя значениями, но я думаю, что приведенный выше код более понятен.

...