SAS существенно отличается от Matlab тем, что в Matlab есть векторы и матрицы, а в базовом SAS их нет. Базовый SAS ближе к SQL, чем к матричному языку; вы управляете столбцами внутри строк. Если вы хотите рассматривать SAS как матричный язык, посмотрите, есть ли у вас SAS-IML
лицензия (PROC SETINIT; RUN;
должно показать вам, что у вас есть лицензия, или обратитесь к администратору SAS). Этот язык очень похож на Matlab.
Что касается использования базового SAS для решения этой проблемы, то, что вы делаете, зависит от вашей цели. Если нужно только сравнить каждую строку с предыдущей строкой [или следующей строкой, поскольку эти две цели идентичны], вы можете легко сделать это с помощью PROC COMPARE
.
Например:
data class_one/view=class_one;
set sashelp.class(firstobs=2);
run;
proc compare base=sashelp.class compare=class_one out=class_compare;
run;
Есть много вариантов с PROC COMPARE
, чтобы получить именно то, что вы хотите, см. документацию для получения более подробной информации.
Вы также можете очень легко выполнить слияние со следующей строкой.
data want;
merge sashelp.class(in=a) sashelp.class(in=b firstobs=2 rename=(...) keep=...);
... do stuff ...
run;
Однако вам нужно переименовать переменные, поступающие из второго набора данных, поскольку в противном случае они перезапишут переменные первого набора данных, и используйте параметр keep
, чтобы сохранить только те, с которыми вы работаете, а keep
использует ИСХОДНОЕ имя, а не переименованное имя. Затем в ...do stuff...
вы помещаете любой код, который используете для сравнения строки со следующей строкой. Если важна «предыдущая строка» (т. е. вы хотите, чтобы в качестве конечного вывода были строки [2..n], а не [1..n-1]), переместите firstobs=2 в первый набор данных. (Это говорит ему пропустить первое наблюдение, поэтому один набор данных начинается с 1, а другой начинается с 2, а затем оба повторяются дальше.)
Если вы просто проверяете номер строки, это немного проще. Ты можешь сделать это:
data want;
set have;
by num notsorted; *notsorted is needed unless you do expect it to be in numeric order;
if first.num then first_obs_for_rownum=1;
if last.num then last_obs_for_rownum=1;
run;
Очевидно, вы можете делать другие вещи с этими пунктами then
, я просто пытаюсь прояснить, что они делают. if first.num and last.num
будет означать, что строка уникальна по номеру строки (по крайней мере, в порядке набора данных - если он не отсортирован, то же число может появиться в другом месте, но не непосредственно перед/после этой строки). first.num
— это переменная 1/0, указывающая, имела ли предыдущая строка другое (1) или такое же (0) значение для num
; last.num
— это переменная 1/0, которая указывает, имеет ли следующая строка другое (1) или такое же (0) значение для num
. Их можно использовать для любой переменной (так что first.id
first.name
и т. д. работают для этих переменных), если они каким-то образом появляются в операторе by
; и если у вас есть оператор by
с несколькими переменными, они сбрасываются каждый раз, когда сбрасывается любая переменная слева от этой переменной.
person
Joe
schedule
04.04.2014
lag()
. Так что вы бы использовалиcurrent=num; prev=lag(num);
. Ссылка на «ячейки» в таблице SAS сбивает с толку, данные упорядочиваются в переменных и наблюдениях (аналогично столбцам и строкам соответственно). - person mjsqu   schedule 04.04.2014lead()
- person mjsqu   schedule 04.04.2014lead()
не существует в базовом SAS, аlag()
не имеет точного доступа к данным предыдущей строки. Его можно использовать так, как если бы он это делал в некоторых случаях, но в этом случае, вероятно, лучше его не использовать. В частности, он НЕ работает так, как вы ожидаете, внутри условных операторов, поэтому, если вы по какой-то причине используетеlag
, вам следует быть осторожным, чтобы присвоить prev безоговорочно. - person Joe   schedule 04.04.2014lead()
, который существует в вариантах SQL, отличных от SAS. Я бы также повторил оговорки по поводуlag()
, по возможности стараюсь их избегать. - person mjsqu   schedule 04.04.2014