Динамический n в функции LAG <n>(переменная) SAS_part2 - PullRequest
0 голосов
/ 28 ноября 2018

знаете ли вы, как использовать n в функции LAGn (переменная), которая ссылается на другую макропеременную в программе -> max в моем случае от V1 ?

   data example1;
input V1 value V2;
datalines;
a 1.0 2.0
a 1.0 1.0
a 1.0 1.0
b 1.0 1.0
b 1.0 1.0
;       

proc sql;
  select max(V2) format = 1. into :n
  from example1;
quit;

data example1;
  set example1;
  by V1;
  lagval=lag&n(V2);
  run;

Кодот пользователя 667489 и работает на один столбец. Теперь n изменяется на V1. Я ожидаю:

          MAX LAG
a 1.0 2.0  2  .
a 1.0 1.0  2  .
a 1.0 1.0  2  2
b 1.0 1.0  1  .
b 1.0 1.0  1  1
;    

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Забудьте о LAG ().Просто добавьте переменную-счетчик и присоединитесь к ней.

Давайте исправим ваш пример данных шага, чтобы он работал.

data example1;
  input V1 $ value V2;
datalines;
a 1 2
a 1 1
a 1 1
b 1 1
b 1 1
;

Теперь добавьте уникальный идентификатор строки в каждой группе BY.

data step1;
  set example1;
  by v1;
  if first.v1 then row=0;
  row+1;
run;

Теперь просто объедините этот набор данных с самим собой.

proc sql ;
 create table want as
   select a.*,b.v2 as lag_v2
   from (select *,max(v2) as max_v2 from step1 group by v1) a
   left join step1 b
   on a.v1= b.v1 and a.row = b.row + a.max_v2
 ;
quit;

Результаты:

Obs    V1    value    V2    row    max_v2    lag_v2

 1     a       1       2     1        2         .
 2     a       1       1     2        2         .
 3     a       1       1     3        2         2
 4     b       1       1     1        1         .
 5     b       1       1     2        1         1

Надеемся, ваш реальный вариант использования имеет больше смысла, чем этот пример.

0 голосов
/ 29 ноября 2018

Функция LAG<n> - это встроенный стек фиксированной глубины, который зависит от места использования кода и, следовательно, состояния шага при вызове.Стек имеет глубину и не может быть динамически изменен во время выполнения.

Динамическое запаздывание может быть реализовано на этапе SAS DATA с использованием хеш-объекта.Техника двойного DOW позволяет измерять группу, а затем обрабатывать ее элементы.

Пример кода

В этом примере используется объект hash, который поддерживает стек значений в пределахгруппа.Первый цикл DOW вычисляет максимум поля, которое становится динамической высотой стека.Второй цикл DOW выполняет итерации группы и извлекает значение задержки, а также создает стек для будущих задержек элементов.

* some faux data;

data have (keep=group value duration);
  do group = 1 to 10;
    limit = ceil(4 * ranuni(6));
    put group= limit=;
    do _n_ = 1 to 8 + 10*ranuni(123);
      value = group*10 + _n_;
      duration = 1 + floor(limit*ranuni(123));
      output;
    end;
  end;
run;

* dynamic lag provided via hash;

data want;
  if _n_ = 1 then do;
    retain index lag_value .;
    declare hash lag_stack();
    lag_stack.defineKey('index');
    lag_stack.defineData('lag_value');
    lag_stack.defineDone();
  end;

  do _n_ = 1 by 1 until (last.group);
    set have;
    by group;
    max_duration = max(max_duration, duration);
  end;

  * max_duration within group is the lag lag_stack height;

  * pre-fill missings ;
  do index = 1-max_duration to 0;
    lag_stack.replace(key: index, data: .);
  end;

  do _n_ = 1 to _n_;
    set have;
    lag_stack.replace(key: _n_, data: value);
    lag_stack.find(key: _n_ - max_duration);
    output;
  end;

  drop index;
run;

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

...