Несколько более изощренных опций, которые могут быть интересны всем, кому нужно сделать это с действительно большим набором данных, где производительность более важна:
- Если ваш набор данныхуже отсортированы по идентификатору, но не по X внутри каждого идентификатора, вы все равно можете сделать это за один шаг данных без какой-либо сортировки, используя сохраненный максимум в каждой группе.В качестве альтернативы вы можете использовать средства proc (согласно верхнему ответу), но с оператором
by
вместо оператора class
- это уменьшает использование памяти.
data sample;
input id x;
datalines;
18 1
18 1
18 2
18 1
18 2
369 2
369 3
369 3
361 1
;
run;
data want;
do until(last.ID);
set sample;
by ID;
xmax = max(x, xmax);
end;
x = xmax;
drop xmax;
run;
Даже если ваш набор данных не отсортирован по идентификатору, вы все равно можете сделать это за один шаг данных, не сортируя его, используя хеш-объект для отслеживания максимального значения x, которое вы нашли для каждого идентификатора на ходу.вместе.Это будет немного быстрее, чем
proc means
, и, как правило, будет использовать меньше памяти, так как proc означает, что выполняет различные вычисления в фоновом режиме, которые не нужны в выходном наборе данных.
data _null_;
set sample end = eof;
if _n_ = 1 then do;
call missing(xmax);
declare hash h(ordered:'a');
rc = h.definekey('ID');
rc = h.definedata('ID','xmax');
rc = h.definedone();
end;
rc = h.find();
if rc = 0 then do;
if x > xmax then do;
xmax = x;
rc = h.replace();
end;
end;
else do;
xmax = x;
rc = h.add();
end;
if eof then rc = h.output(dataset:'want2');
run;
В этом примерена моем ПК хэш-подход использовал столько памяти:
memory 966.15k
OS Memory 27292.00k
против.это много для эквивалентной сводки процедур:
memory 8706.90k
OS Memory 35760.00k
Неплохая экономия, если она действительно нужна для увеличения!