Вы правы, что переменная retain
будет переносить значение в прямые итерации шага данных. Номинально простой шаг данных с одним оператором set
итерацией будет соответствовать строке в наборе данных.
Ваша сохраненная переменная должна быть назначена в начале группы, поэтому вам понадобится оператор by
, который, в свою очередь, сделает доступной автоматическую переменную флага first.<by-group-var>
.
data have; input
Group X Y; datalines;
10600 1 1
10600 1 2
10600 1 3
10800 2 1
10800 2 3
10900 1 2
10900 1 3
11100 2 2
11100 2 2
11100 2 3
11100 2 2
11200 2 3
11300 2 1
11300 2 2
11300 1 3
11300 1 3
11300 1 3
11300 1 3
run;
Последний набор строк с group=11300
имеет x=2
, за которым следует x=1
. Ваш рассказ
внутри группы
передает идею, но не является точным. Фактическая группировка (основанная на показанном желании) представляется комбинацией group
и x
. Таким образом, вам понадобится
by group x notsorted;
заявление. notsorted
заставит шаг данных установить first.
и last.
на основе случайности значений вместо явного упорядочения значений.
data want;
set have;
by group x nostsorted;
retain z;
if first.x then do; * detect first row in combinations "group/x";
select;
when (X=1 & Y=1) Z=1; * apply logic for retained value;
when (X=2 & Y=1) Z=2;
when (X=1 & Y=2) Z=3;
when (X=2 & Y=2) Z=4;
otherwise Z=.;
end;
end;
logic_tracker_first_x = first.x;
run;
ods listing; options nocenter;
proc print data=want;
run;
В окне вывода отображается
logic_tracker_
Obs Group X Y z first_x
1 10600 1 1 1 1
2 10600 1 2 1 0
3 10600 1 3 1 0
4 10800 2 1 2 1
5 10800 2 3 2 0
6 10900 1 2 3 1
7 10900 1 3 3 0
8 11100 2 2 4 1
9 11100 2 2 4 0
10 11100 2 3 4 0
11 11100 2 2 4 0
12 11200 2 3 . 1
13 11300 2 1 2 1
14 11300 2 2 2 0
15 11300 1 3 . 1
16 11300 1 3 . 0
17 11300 1 3 . 0
18 11300 1 3 . 0