Если ваши данные точно так, как вы говорите, то вы можете использовать слияние взглядов. Он буквально берет набор данных и сливается с копией набора данных, который начинается в строке 2, бок о бок. Вам просто нужно проверить, что вы все еще на одном ID. Это меняет значение x для все записывает значение, следовательно, не только первое; вы можете добавить дополнительный код, чтобы обратить на это внимание (но не можете использовать FIRST и LAST).
data want;
merge have have(firstobs=2 rename=(id=newid x=newx));
if newid=id then x=newx;
keep x id;
run;
Если у вас нет каких-либо дополнительных переменных, представляющих интерес, то вы можете сделать что-то еще более интересное: дублировать вторую строку в полном объеме и удалить первую строку.
data want;
set have;
by id notsorted;
if first.id then do;
firstrow+1;
delete;
end;
if firstrow=1 then do;
firstrow=0;
output;
end;
output;
run;
Однако, «безопасный» способ (с точки зрения делать, скорее всего, что вы хотите точно), заключается в следующем, что петля DoW.
data want;
idcounter=0;
do _n_ = 1 by 1 until (last.id);
set have;
by id notsorted;
idcounter+1;
if idcounter=2 then second_x = x;
end;
do _n_=1 by 1 until (last.id);
set have;
by id notsorted;
if first.id then x=second_x;
output;
end;
run;
Это определяет второе х в первом цикле, для этого по группам, а затем во втором контуре устанавливает его в правильное значение для строки 1 и выходов.
В обоих последних примерах я предполагаю, что ваши данные организованы по идентификатору, но не по-настоящему отсортированы (например, ваш первоначальный пример). Если он не организован по идентификатору, сначала необходимо выполнить сортировку (но затем удалить NOTSORTED).
У вас есть пакет SAS/ETS? Если это так, может помочь Proc Expand с преобразованием свинца. – Reeza