2.3 Работа с numeric и char переменными

Арифметические операторы

Ниже приведена таблица арифметических операторов в sas.

Operation Symbol Assignment Statement Action Taken Priority
addition + a = b + c; add b and c Lowest
subtraction - a = b - c; subtract c from b Lowest
multiplication * a = b * c; multiply b and c Next Highest
division / a = b / c; divide b by c Next Highest
exponentiation ** a = b ** c; raise b to the power of c Highest
negative prefix - a = -b; take the negative of b Highest

Здесь никаких проблем возникнуть не должно, поэтому хотелось бы сразу отправиться дальше и рассмотреть список часто используемых функций для numeric переменных

Функции для numeric переменных

Название функции Описание Синтаксис Пример
int Целая часть от числа a=int(x);
abs Абсолютное значение a=abs(x);
sqrt Извлечение квадратного корня a=sqrt(x);
min* Минимальное значение a=min(x,y,z);
max* Максимальное значение a=max(x,y,z);
sum* Сумма a=sum(x,y,z);
mean* Среднее a=mean(x,y,z);
round Округление

a=round(x); - округление до целого

a=round(x,1); - округление до целого

a=round(x,.1); - округление до десятых

a=round(x,.01); - округление до сотых

log Логарифм a=log(x);
exp Экспонента a=exp(x);
dif Разница с предыдущим значением a=dif(x);
n* Количество непустых значений a=n(x);
nmiss* Количество пустых значений

a=nmiss(x);

a=nmiss(x,y,z);

floor Ближайшее целое число снизу a=floor(x);
ceil Ближайшее целое число сверху a=ceil(x);
coalesce Возвращает первое непустое значение из списка числовых аргументов a = coalesce(x, y, z);

* - имеет смысл использовать с несколькими аргументами

Функции/операторы для character переменных

Теперь давайте составим такой же список функций для строковых переменных.

Название функции/ оператора Описание Синтаксис Пример
length Возвращает длину непустой строки (без пробелов в конце) a=length(x);
upcase Меняет все буквы в строке на заглавные a=upcase(x);
lowcase Меняет все буквы в строке на маленькие a=lowcase(x);
propcase Каждую первую букву в слове меняет на заглавную, остальные на маленькие a=propcase(x);
compress Возвращает строку без указанных символов a=compress(x,’s’);
compbl Возвращает строку убрав все лишние пробелы (лишние – начиная со второго подряд) a=compbl(x);
|| или !! Конкатенация – соединяет две строки

a=x||y||z;

a=x!!y!!z;

left Прижимает влево a=left(x);
right Прижимает вправо a=right(x);
trim Обрезает пробелы в конце a=trim(x);
strip Обрезает пробелы в конце и начале a=strip(x);
cat Соединяет (конкатенирует) две строки a=cat(x,y,z);
cats Соединяет две строки, обрезая пробелы в начале и в конце a=cats(x,y,z);
catt Соединяет две строки, обрезая пробелы только конце a=catt(x,y,z);
catx Соединяет две строки, обрезая пробелы в начале и в конце, при этом между строками вставляет указанный разделитель a=catx('string',x,y);
find Ищет указанную строку в другой строке и возвращает положение начала искомой строки a=find(x,’string’);
findw Ищет слово в строке. Возвращает положение начала слова. a=findw(x,’s’);
index Ищет строку. Возвращает первое значение. a=index(x,’string’);
anydigit Ищет любое число в строке. Возвращает положение числа в строке, если нашел, или 0, если не нашел. a=anydigit(x);
anyalpha Ищет любую букву в строке. Возвращает положение первой буквы в строке, если нашел, или 0, если не нашел a=anyalphat(x);
scan Сканирует строку и возвращает n-ое слово в строке a=scan(x,2,”-“);
substr Создает «подстроку» из другой строки a=substr(x,2,5);
tranwrd Меняет подстроки в строке. a=tranwrd(x,’old’,’new’);
coalesceс Аналог coalesce для строк. Возвращает первое непустое значение из списка строковых аргументов. a = coalescec(x, y, z);

Функции/операторы для всех типов

И еще один список. Эти функции одинаково хорошо работают как с character так и с numeric переменными.

Название функции Описание Синтаксис Пример

lag

lagn

Возвращает предыдущее значение по умолчанию с шагом 1.

Lagn возвращает предыдущее значение с шагом n.

a=lag(x);

a=lag2(x);

missing Проверяет пустое ли значение. Если пустое возвращает 1, если нет - 0.

a=missing(x);

if missing(x) then ...

if not missing(x) then ...

call missing Очищает переменные.

call missing(x);

call missing(x,y);

call missing(of x1-x2);

call missing (of _all_);

call missing (of _char_);

call missing (of _numeric_);

Даты в SAS

SAS может зачитывать даты практически любого формата, как, например, такие:

Дата Описание
10/21/1950 Month/Day/Year
21-10-1950 Day-Month-Year
21Oct1950 Day Month Abbreviation Year
50294 Julian Date

Однако все они хранятся в SAS как число, а именно, количество дней с 1 Января 1960 года (все даты, после этой – это положительные числа, до - отрицательные). Вот пример как в SAS хранятся даты:

Дата SAS значение
January 1, 1960 0
January 2, 1960 1
December 31, 1959 -1
June 15, 2006 16967
October 21, 1950 -3359

Давайте теперь познакомимся с некоторыми часто используемыми форматами для даты. Для этого рассмотрим следующий отрывок кода

data test;
    data = 1;
    
    format date date9.;
run;

Как мы уже с вами знаем, значение 1 в SAS соответствует дате 2 Января 1960. Однако, накладывая формат на переменную date, мы можем менять внешний вид этой даты. Давайте посмотрим на самые часто используемые форматы и то, как будет выглядеть одна и та же дата под разными форматами.

Название формата Результат
date9. 02JAN1960
date. 02JAN60
is8601da. 1960-01-02
ddmmyy10. 02/01/1960
ddmmyy8. 02/01/60
ddmmyy. 02/01/60
mmddyy10. 01/02/1960
mmddyy. 01/02/60
yymmdd6. 600102
yymmdd8. 60-01-02
yymmdd10. 1960-01-02

Это далеко не полный перечень всех существующих форматов, больше можно посмотреть, например, здесь support.sas.com

Особое внимание следует обратить на эти два формата: ddmmyy. и mmddyy. Бывают случаи, когда их можно перепутать. В частности, если в данных не встретилось дня больше 12, тогда сложно понять, что же тут день, а что месяц. В таких ситуациях, всегда лучше перестраховаться и уточнить.

Бывают случаи, когда вам нужно руками ввести какую-то определенную дату, чтобы что-то посмотреть, или проверить, или это какая-то значимая дата внутри проекта и вам нужно ее часто использовать и т.д. Например, это 06JUL1991. Согласитесь, навскидку и не скажешь сколько же это дней после 01JAN1960. Было бы странным, если бы SAS не оставил нам возможности ввести дату, как число, которое хранится в SAS, однако на понятном человеку языке. Я думаю, что было бы немало проблем, если всякий такой раз нужно было отдельно вычислять разницу с 01JAN1960 и вводить дату только как целое число. Для того, чтобы ввести дату, но чтобы SAS понял, что это именно дата, а не что-то другое, необходимо записать ее как date constant:

'06JUL1991'd

Давайте проверим, что же из этого получится.

data test;
    a='06JUL1991'd;
run;
Lesson2.3.1

Как видим, SAS распознал, что это дата и хранит ее как целое число. К сожалению, для date constant есть некоторые требования. Она обязательно должна выглядеть следующим образом: <1-2 цифры дня> <трехбуквенная аббревиатура месяца> <2 или 4 цифры года> в одинарных или двойных кавычках после чего d или D. Т.е. такую запись ‘01/06/1991’d SAS не распознает и в придачу ругнется на вас в логе.

А теперь давайте представим следующую ситуацию. Допустим, пациенту измерили давление в тот же день когда он принял исследуемый препарат. И представим даже, что давление это оказалось не совсем в норме. И вот тут вам важно очень знать, измерили давление до приема лекарства или после. Ведь если после, то, возможно, повышение давления связано именно с приемом этого лекарства. В таком случае вам нужно время замера и время приема лекарства. На практике, работать с датой/временем приходится очень часто, поэтому давайте поговорим о времени в SAS.

Посмотрим, чему соответствует 0, 1, 2 в SAS, наложи мы на него формат datetime16.

SAS значение Дата/Время
0 01JAN60:00:00:00
1 01JAN60:00:00:01
2 01JAN60:00:00:02

Как видим, мы уже имеем другие значения, не те, что были в примере с датами. Это говорит нам о том, что накладывая формат или делая какие-либо преобразования с датами, мы должны четко понимать, что именно хранится в переменной, иными словами, чему будет соответствовать единица – первой секунде первого января 60 года, или второму января 60 года.

После того, как мы убедились, что в нашей переменной хранится значение datetime, давайте посмотри, как будет выглядеть значение 20000 под разными форматами.

Название формата Результат
datetime. 01JAN60:05:33:20
datetime16. 01JAN60:05:33:20
datetime14. 01JAN60:05:33
is8601dt. 1960-01-01T05:33:20
dateampm. 01JAN60:05:33:20 AM
hhmm. 5:33
time. 5:33:20
time5. 5:33
is8601tm. 05:33:20
tod. 05:33:20
tod5. 05:33

Более подробно можно посмотреть все по той же ссылке, что указана выше. support.sas.com

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

Давайте рассмотрим несколько примеров того, как именно работает эта функция:

Expression Value Returned
intck('year', '01Jan2005'd, '31Dec2005’d) 0
intck ('year', '31Dec2005'd, '01Jan2006’d) 1
intck ('month', '01Jan2005'd, '31Jan2005'd) 0
intck ('month', '31Jan2005'd, '01Feb2005'd) 1
intck ('qtr', '25Mar2005'd, '15Apr2005'd) 1

Как мы видим, в первом случае intck вернет нам значение 0, т.к. обе даты – в пределах одного календарного года, в то время как во втором случае мы один раз пересекли границу интервала и в итоге получили значение 1. Аналогично с интервалами month и qtr.

Дополнительные материалы: