2014-10-30 2 views
1

Надеюсь, это не дублирующий вопрос. Я искал форум и сохраняю функцию, кажется, выбор оружия, но он копирует наблюдение, и я пытаюсь сделать следующее: для данного идентификатора, скопируйте вторую строку в первую строку для значения x. также первое значение x всегда 2.Скопируйте значение из строки ниже в SAS

Вот мои данные;

id x 
3 2 
3 1 
3 1 
2 2 
2 1 
2 1 
6 2 
6 0 
6 0 

и я хочу, чтобы это выглядело так;

id x 
3 1 
3 1 
3 1 
2 1 
2 1 
2 1 
6 0 
6 0 
6 0 

и вот стартовый код;

data have; 
input id x; 
cards; 
3 2 
3 1 
3 1 
2 2 
2 1 
2 1 
6 2 
6 0 
6 0 
; 
run; 
+0

У вас есть пакет SAS/ETS? Если это так, может помочь Proc Expand с преобразованием свинца. – Reeza

ответ

2

Свинец сложный в SAS. Вы можете сортировать в обратном порядке и использовать функцию задержки, чтобы обойти его, но вы правы: оператор сохранения позволяет нам добавить переменную заказа, чтобы мы могли отсортировать ее до исходного формата.

data have; 
set have; 
retain order; 
lagid = lag(id); 
if id ne lagid then order = 0; 
order = order + 1; 
drop lagid; 
run; 

proc sort data=have; by id descending order; run; 

data have; 
set have; 
leadx = lag(x); 
run; 

proc sort data=have; by id order; run; 

data have; 
set have; 
if order = 3 then x_fixed = x; 
else x_fixed = leadx; 
run; 
+0

это аккуратное решение, спасибо :) – Gokay

0

Если ваши данные точно так, как вы говорите, то вы можете использовать слияние взглядов. Он буквально берет набор данных и сливается с копией набора данных, который начинается в строке 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).

Смежные вопросы