Как посчитать длину ненулевой последовательности в SAS

#sas

#sas

Вопрос:

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

 ID  Value  
1     0  
1     0  
1     2.5  
1     3  
1     0  
1     4  
1     2  
1     5  
1     0  
  

Итак, здесь длина первой ненулевой последовательности равна 2, а длина второй ненулевой последовательности равна 3. Новые данные будут выглядеть следующим образом:

 ID  Value  Length  
1     0    0  
1     0    0  
1     2.5  2   
1     3    2  
1     0    0  
1     4    3  
1     2    3  
1     5    3   
1     0    0  
  

Как я могу написать код SAS для выполнения этой задачи с такими большими данными, как это. Спасибо!

Комментарии:

1. Нужно ли сохранять каждую из длин? Какой ваш желаемый результат? Новый набор данных с переменной, представляющей эти длины (вниз по столбцу), или что-то еще?

2. ДА. Мне нужно сохранить длину в новой переменной. Я отредактировал свой вопрос, как указано выше.

Ответ №1:

Вот одно из возможных решений. Предполагается, что в переменной Value нет пропущенных значений и что ваша переменная ID не имеет никакого значения для этой проблемы.

 *creates new length variable that starts at 1 and increments by 1 from start to end of every non-zero sequence;
data step_one (drop=prev_val);
   set orig_data;
   retain prev_val length 0;
   indx = _n_;
   if value ne 0 and prev_val ne 0 then length = length   1;
   else if value ne 0 then length = 1;
   else if value = 0 then length = 0;
   prev_val = value;
run;

*sorts dataset in reverse order;
proc sort data=step_one;
   by descending indx;
run;

*creates modified length variable that carries maximum length value for each sequence down to all observations included in that sequence;
data step_two (drop=length prev_length rename=(length_new=length));
   set step_one;
   retain length_new prev_length 0;
   if length = 0 then length_new = 0;
   else if length ne 0 and prev_length = 0 then
      length_new = length;
   prev_length = length;
run;

*re-sorts dataset back to its original order and outputs final dataset with just the needed variables;
proc sort data=step_two out=final_result (keep=ID value length);
   by indx;
run;