2013-03-19 1 views
4

Я очень новичок в SAS, и я пытаюсь выяснить некоторые основные вещи, доступные на других языках.SAS: Как я могу указать на конкретное наблюдение за значением?

У меня есть таблица

ID Number 
-- ------ 
1 2 
2 5 
3 6 
4 1 

Я хотел бы создать новую переменную, где я просуммировать значения одного наблюдения Количество друг к другу наблюдений, как

Number2 = Number + Number[3] 

ID Number Number2 
-- ------ ------ 
1 2  8 
2 5  11 
3 6  12 
4 1  7 

Как я значение третьего наблюдения числа и добавить это к каждому наблюдению Number в новой переменной?

+0

У вас есть SAS/IML или просто база SAS? – Joe

ответ

2

Начну с того, что Base SAS действительно не работает таким образом, как правило; это не то, что он не может, но обычно вы можете решить большинство проблем, не указывая на определенную строку.

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

Тем не менее, конкретный пример, вы даете тривиальна:

data have; 
input ID Number; 
datalines; 
1 2 
2 5 
3 6 
4 1 
;;;; 
run; 

data want; 
set have; 
_t = 3; 
set have(rename=number=number3 keep=number) point=_t ; 
number2=number+number3; 
run; 

Если у вас есть SAS/IML (матрица языка для SAS), которая несколько похожа на R, то это совсем другая история, как в ваша вероятность выполнить эту операцию и как вы это сделаете.

proc iml; 
a= {1 2, 2 5, 3 6, 4 1}; *create initial matrix; 
b = a[,2] + a[3,2]; *create a new matrix which is the 2nd column of a added 
         elementwise to the value in the third row second column; 
c = a||b; *append new matrix to a - could be done in same step of course; 
print b c; 
quit; 

Чтобы сделать это с первого наблюдения, это намного проще.

data want; 
set have; 
retain _firstpoint; *prevents _firstpoint from being set to missing each iteration; 
if _n_ = 1 then _firstpoint=number; *on the first iteration (usually first row) set to number's value; 
number = number - _firstpoint; *now subtract that from number to get relative value; 
run; 

Я расскажу немного подробнее об этом. SAS работает на уровне записи по записи, где каждая запись независимо обрабатывается на этапе DATA. (PROC, с другой стороны, не могут вести себя так, хотя многие делают на некотором уровне).SAS, подобно SQl и аналогичным базам данных, действительно не признает, что любая строка является «первой» или «второй» или «nth»; однако, в отличие от SQL, он позволяет вам притворяться, что он основан на текущей сортировке. Метод POINT = случайный доступ - это один из способов сделать это.

В большинстве случаев вы собираетесь использовать что-то в данных, чтобы определить, что вы хотите делать, а не некоторые, связанные с упорядочением данных. Вот как вы могли бы сделать то же самое, что и метод POINT =, но используя значение ID:

данные хотят; if n = 1 затем установите have (where = (ID = 3) rename = number = number3); комплект есть; номер2 = номер + число3; run;

, что в первой итерации шага данных (_N_ = 1) принимает строку из ИМЕЙТЕ, где Id = 3, а затем принимает строку из имеет по порядку (на самом деле это делает это :)

*check to see if _n_=1; it is; so take row id=3; 
*take first row (id=1); 
*check to see if _n_=1; it is not; 
*take second row (id=2); 
... continue ... 

Переменные, которые содержатся в инструкции SET, автоматически сохраняются, поэтому NUMBER3 автоматически сохраняется (yay!) И не устанавливается на отсутствие между итерациями цикла шагов данных. Пока вы не изменяете значение, оно останется для каждой итерации.

+0

Хорошо, я вижу, что это не так тривиально по сравнению с MATLAB и R. Я согласен, что в реальных сценариях у вас будет ключ, но я просто подумал, что это будет так же просто, как с MATLAB и R. В моем конкретном примере я ' (число дат SAS), и я хотел бы вычесть дату первого наблюдения для всех наблюдений, чтобы получить смещение по времени от 0. Будет ли это проще? – Morten

+0

Это было бы намного проще, на самом деле. Во-первых, SAS имеет PROC (по существу скомпилированные двоичные файлы), которые часто выполняют операции на уровне набора данных; ETS - это модуль с временными рядами PROC, которые могут работать (у меня нет опыта с ними, но это точка всего модуля). Я добавлю пример первого наблюдения в ответе. – Joe

+0

Отлично - это сработало. Спасибо огромное! – Morten

4

Существует несколько способов сделать это; здесь один, используя опцию SAS POINT=:

data have; 
    input ID Number; 
datalines; 
1 2 
2 5 
3 6 
4 1 
run; 

data want; 
    retain adder; 
    drop adder; 
    if _n_=1 then do; 
     adder = 3; 
     set have point=adder; 
     adder = number; 
     end; 

    set have; 
    number = number + adder; 
run; 

В RETAIN и DROP заявления определить переменную временную удерживать значение, которое вы хотите добавить. RETAIN означает, что значение не должно быть повторно инициализировано без потери каждый раз через шаг данных, а DROP означает, что вы не хотите включать эту переменную в выходной набор данных.

Опция POINT= позволяет считывать определенное наблюдение из набора данных SAS. Часть _n_=1 является механизмом управления только для выполнения этого бита кода один раз, присваивая переменной adder значение третьего наблюдения.

Следующий раздел читает набор данных по одному наблюдению за раз, и добавление применяет ваши изменения.

Обратите внимание, что один и тот же набор данных считывается дважды; удобная функция SAS.