Валидационный макрос sas что это
В чем уникальность и преимущество SAS MACRO перед процедурами SAS? Если цель макроса состоит в том, чтобы уменьшить усилия по повторению задач для разных входных данных, нельзя ли это сделать также в виде процедур?
Пользователи SAS действительно могут создавать свои собственные SAS PROC. Им необходимо получить лицензию на SAS / Toolkit и код на C или некоторых других языках.
SAS состоит из множества разных частей. Макрос является (или был) наиболее (и, вероятно, единственным) универсальным инструментом в SAS, который может соединять (почти любые, но не все) части вместе. Учитывая, насколько примитивен и странен макрос (язык), это немного забавно, но это правда.
Вы можете создать собственный макрос без инструментария лицензирования - и, насколько я помню, не многие люди используют SAS Toolkit для пользовательских процедур.
Макросы помогают многократно запускать программы с настраиваемыми параметрами и неоценимы для манипулирования и создания переменных.
Procs обычно являются устройствами вывода. макросы также могут помочь с повторяющимися пошаговыми манипуляциями с данными.
Большинство процедур SAS выполняют определенные операции с данными. Макросы позволяют выполнять условную обработку блоков кода SAS во время выполнения, такую как повторение вызова процедуры для разных наборов данных с использованием цикла DO или решение выполнить шаг данных в зависимости от того, существует ли файл.
Хотя код кажется неуклюжим для новичков, на самом деле его относительно легко понять, когда вы изучите BASE SAS, поскольку синтаксис почти идентичен (с добавлением% s и @s для вкуса).
Существует множество вариантов использования и расширенных функций макросов, но в основном я использую их просто, чтобы стараться оставаться верным СУХИЙ принцип. Если вы оказались в ситуации, когда вы часто повторяете блоки кода, возможно, вы захотите это сделать. Например, я экспортирую наборы данных, чтобы всегда отличаться. Если я сделаю это несколько раз в своем коде, я просто вставлю код в макрос:
Затем, когда я продолжу свой код. Я создаю набор данных и хочу его экспортировать, я могу просто написать:
Это одна простая строка, которую я должен записать 30 раз в один файл вместо того, чтобы писать 7 или 8 строк 30 раз. Это упрощает отслеживание ошибок, и если я хочу что-то изменить в том, как я экспортирую, мне просто нужно изменить это в одном месте.
Я использую его не только для экспорта, но он должен дать вам общее представление.
Если вы знакомы с другими языками, макроязык sas покажется вам довольно неудобным и громоздким, но это определенно лучше, чем ничего.
Это все равно что спросить, зачем нам Perl, Python, ksh, bash и т. Д., Когда у нас есть все программы, доступные в UNIX. Макросы - это язык сценариев, который дает пользователям большую гибкость и контроль над тем, что они хотят от SAS. Вы также можете легко сгенерировать динамический код. Существующие процедуры довольно жесткие в том, что они могут принимать в качестве входных и что вы получаете в качестве выходных. Proc FCMP открыл этап обработки данных для пользовательских функций, но это по-прежнему не может заменить гибкость, которую дает макроязык.
SAS имеет мощную функцию программирования под названием Macros, которая позволяет нам избегать повторяющихся участков кода и использовать их снова и снова, когда это необходимо. Это также помогает создавать в коде динамические переменные, которые могут принимать разные значения для разных экземпляров прогона одного и того же кода. Макросы также могут быть объявлены для блоков кода, которые будут многократно использоваться аналогично макропеременным. Мы увидим оба из них в следующих примерах.
Макропеременные
Это переменные, которые содержат значение, которое будет снова и снова использоваться программой SAS. Они объявляются в начале программы SAS и вызываются позже в основной части программы. Они могут быть глобальными или локальными по объему.
Глобальная макро-переменная
пример
Ниже приведен пример переменной SAS с именем SYSDATE, которая представляет системную дату. Рассмотрим сценарий для печати системной даты в заголовке отчета SAS каждый день, когда отчет генерируется. Заголовок покажет текущую дату и день без кодирования каких-либо значений для них. Мы используем встроенный набор данных SAS под названием CARS, доступный в библиотеке SASHELP.
Когда приведенный выше код выполняется, мы получаем следующий вывод.
Локальная переменная макроса
Эти переменные могут быть доступны для программ SAS, в которых они объявлены как часть программы. Они, как правило, используются для предоставления разных varaibels одним и тем же операторам SAS, чтобы они могли обрабатывать разные наблюдения набора данных.
Синтаксис
Локальные переменные имеют декальтарный синтаксис.
пример
Переменные используются операторами SAS с использованием символа &, добавляемого в начале имени переменной. Ниже программа собирает все наблюдения за маркой «Ауди» и типом «Спорт». В случае, если мы хотим получить результат другого make , нам нужно изменить значение переменной make_name без изменения какой-либо другой части программы. В случае программ переноса эта переменная может быть снова и снова указана в любых операторах SAS.
Когда приведенный выше код выполняется, мы получаем тот же вывод, что и предыдущая программа. Но давайте изменим имя типа на «Wagon» и запустим ту же программу. Мы получим следующий результат.
Использование параметров в макросах SAS
Существует два типа параметров макроса: позиционные и с ключами.
Позиционные параметры
Позиционные параметры используются для передачи значений параметров в соответствии с положением параметра в определении макроса и при вызове. Порядок указания параметров должен соответствовать порядку, в котором они указаны в инструкции %MACRO. При указании нескольких позиционных параметров используйте запятую для разделения параметров. Если параметр не указан, соответствующей переменной макроса, указанной в инструкции %MACRO, присваивается значение null.
Пример приведен ниже:
Параметры с ключами
Преимущество использования параметров с ключами — возможность указать значение по умолчанию для переменных макроса в определении макроса. При использовании параметров с ключами необходимо указать знак равенства после имени макропеременной.
Пример приведен ниже:
Если в определении макроса используются и позиционные параметры, и параметры с ключами, позиционные параметры должны идти первыми. В противном случае появится следующая ошибка:
Пример приведен ниже:
PARMBUFF
Параметр PARMBUFF создает переменную макроса &SYSPBUFF, которая содержит весь список значений параметров, включая круглые скобки. Это позволяет передавать переменное число значений. В следующем примере вы можете передать макросу любое количество параметров. В следующем примере показано, как проанализировать каждое слово в списке параметров:
Если указан параметр PARMBUFF и определение макроса включает в себя как позиционные, так и ключевые параметры, параметры все равно получают значения при вызове макроса. В этом случае весь список вызовов присваивается &SYSPBUFF. Пример приведен ниже:
Обратите внимание, что &SYSPBUFF включает весь список параметров (включая круглые скобки), но каждый отдельный параметр все равно получает собственное значение.
Если вам нужно знать все значения параметров, которые передаются макросу, укажите параметр PARMBUFF в определении макроса, чтобы получить доступ к &SYSPBUFF, который содержит все значения параметров. Дополнительную информацию о PARMBUFF, см. в разделе Выражение %MACRO в статье SAS® 9.4, язык макросов: справочник, пятое издание.
SAS Macro language – это основной и, чуть ли не единственный, инструмент повторного использования кода в SAS. В данном уроке рассматриваются основные его возможности.
Простой пример макро кода:
Оператор title задает заголовок, который выводится в окне Output. Обратите внимание на строку, которая задана в этом операторе: в этой строке используются макро переменные &sysdate9 и &systime . Это встроенные в SAS макро переменные, они хранят значение даты и времени начала текущей сессии SAS (то есть ту дату и время, когда вы запустили SAS).
В результате выполнения программы в окне Output вы увидите:
Как видите, макро переменная &sysdate9 преобразовалась в строку 23SEP2016, а &systime в строку 22:15.
Пользователь может самостоятельно создавать макро переменные и присваивать им значения. Один из способов это сделать – воспользоваться макро оператором %LET. Заметьте, все макро переменные начинаются со знака ‘&’, все макро операторы со знака ‘%’.
Итак, создадим свою макро переменную и воспользуемся ею:
Если значение переменной STUDYID должно быть одно и то же во всех датасетах в пределах данного исследования, то хорошим приемом будет задать глобальную макро переменную "&study" и пользоваться ею во всех программах.
Теперь рассмотрим пример создания простого макроса.
Создание макроса всегда начинается с макро оператора %macro и заканчивается макро оператором %mend. Данный код создает макрос reldays, в качестве параметров, принимает макро переменные date, rel_date, rel_days. Назначение макроса уже должно быть понятным: посчитать количество дней от «базовой» даты rel_date до даты date.
Применим макрос для датасета AE:
Будем иметь в виду, что все даты в датасете AE являются строковыми переменными, а макрос reldays рассчитан на использование числовых
Итак, внутри дата степа мы вызываем макрос reldays с помощью знака ‘%’, и передаем ему такие параметры:
- в качестве первого параметра date – AESTDT;
- в качестве второго параметра rel_date – RFSTDT;
- в качестве третьего – AESTDY.
Как работает этот код.
Если утрировать, SAS “подставляет” на место вызова %reldays(AESTDT, RFSTDT, AESTDY) код макроса, затем, на места макро переменных “подставляет” их значения, и только потом, выполняет получившийся датастеп. В логе можно видеть, как это происходит (опция MPRINT должна быть активна)
Результатом выполнения будет датасет ae_reldays:
Мы познакомились с понятиями макро переменных и макро операторов, рассмотрели несколько примеров их использования, а также создали и применили простейший макрос. Далее углубимся еще немного в эту тему.
Макро переменные могут быть локальными и глобальными.
- Локальные – это переменные, которые действительны только в теле макроса (в куске кода от оператора %macro до оператора %mend).
- Глобальные макро переменные действительны в течение всей сессии SAS, как в открытом коде, так и внутри любого макроса (только если локальная переменная с тем же именем временно не “перекрыла” глобальную).
Рассмотрим еще способы создания макро переменных и изучим области их действия на примерах.
Оператор %GLOBAL создает глобальные макро переменные с пустыми значениями. Чтобы задать этим макро переменным другие значения, можно использовать оператор %LET. Оператор %GLOBAL можно использовать как в открытом коде, так и в теле макроса – результат будет тот же.
Оператор %LOCAL создает локальные макро переменные с пустыми значениями. Этот оператор не может быть использован в открытом коде, только в теле макроса. Для переопределения значений так же используется оператор %LET.
В открытом коде мы имеем доступ только к глобальным переменным. В теле макроса доступны как глобальные, так и локальные. Локальные и глобальные макро переменные с одним и тем же именем не конфликтуют. Это значит, что в теле макроса может быть создана макро переменная с тем же именем, что и глобальная, при этом значение глобальной переменной останется неизменным, а внутри макроса SAS будет использовать значение локальной переменной.
Уже известный вам оператор %LET создает новую макро переменную, но только в том случае, если ранее не существовало переменной с таким именем, в противном случае – просто переопределяет значение уже существующей. Причем, если это тело макроса, то, сперва, оператор попытается переопределить значение локальной макро переменной, если же локальной с таким именем не существует, то переопределяется значение глобальной, и если не существует глобальной – будет создана новая локальная макро переменная.
Поскольку в открытом коде локальные переменные недоступны, оператор %LET в открытом коде создает или переопределяет только глобальные макро переменные.
Несколько слов о синтаксисе:
%let variable_name = <value>;
На месте <value> может быть как обычная строка, так и выражение содержащее другие макро переменные. Если опустить <value>, то значение макро переменной будет пусто
%let var1 = "PINK"; в результате, var1 = "PINK"
%let var2 = color; в результате, var2 = color
%let var3 = The &var2 is &var1; в результате, var3 = The color is "PINK"
Оператор %PUT позволяет увидеть в логе значение любой макро переменной, если она существует.
Рассмотрим пример, когда глобальная и локальная макро переменные имеют одно и то же имя:
- Создаются две глобальные макро переменные, variable1 и variable2, им присваивается значение 1;
- В макросе test_macro создаются две локальные макро переменные, variable1 и variable3. Им обоим присваиваются значение 2. Так же обратите внимание, что переменной variable2 так же присваивается значение 2.
Теперь, подумайте и определите, какими будут значения трех макро переменных variable1, variable2 и variable3 до, после и во время выполнения макроса test_macro. Теперь проверьте ваш ответ, посмотрев в лог программы:
Что еще необходимо знать о макро переменных?
Макро переменная – это всегда строка. Рассмотрим код:
Можно было бы ожидать, что макро переменная square будет содержать результат выполнения арифметических действий, square = 3.14 * (50**2) = 7850. Но это не так.
В логе мы увидим,
Если же мы хотим в переменной square хранить площать круга, то мы должны «заставить» SAS в процессе замещения макро переменных их значениями преобразовать строку в число и выполнить арифметические действия. Это делается с помощью макро функций %EVAL и %SYSEVALF. Подробнее о них, и о других макро функциях смотрите здесь Macro Functions.
Стоит отметить, что SAS в некоторых случаях умеет автоматически выполнять это преобразование. Например, в дата степе, когда значение числовой переменной вычисляется с помощью макро переменной:
Тут макро переменная &p преобразовалась в число без дополнительных усилий.
Еще несколько особенностей, о которых нужно помнить, работая с макро переменными.
- SAS прекрасно распознаёт макро переменные внутри двойных кавычек. Более того, внутри двойных кавычек работают макро функции, макро операторы и сами макросы. А вот макро код в одинарных кавычках не распознается и обрабатывается как обычный текст.
- Обычно SAS сам определяет где в коде макро переменная: началом служит &, а окончанием – любой невалидный символ SAS-имени. Например, в коде %let var = &sysdate-date; макропеременная &sysdate определится и преобразуется в соответствующую строку, поскольку ‘-’ не может являться частью имени в SAS. Мы получим макро переменую var = 23SEP16-date . А вот такой вариант: %let var = &sysdatedate; не даст нам нужного результата, поскольку макро переменной &sysdatedate не существует. Таким образом, в некоторых случаях, нам необходимо «подсказать» системе где заканчивается имя нужной макро переменной. Для этого служит точка. То есть, если выполнить %let var = &sysdate.date;, то получим макро переменную var = 23SEP16date .
Обратите внимание на запись format AESTDT & date_format .. ; Тут мы хотим наложить на переменную AESTDT, формат, который задан в макро переменной &date_format. Если мы поставим одну точку после имени: format AESTDT & date_format. ; - эта точка «скушается» SASом в счет имени самой макро переменной. Выполним такой код и обратим внимание на лог:
Лог программы (опция SYMBOLGEN должна быть активна):
То есть, SAS просто не будет знать, что date9 - это формат.
Как и макро переменные, макросы – это, по сути, текст, который будет подставлен в код там, где макрос был вызван. Конечно, по сравнению с макро переменными, у макросов больше возможностей:
- Макросы могут содержать определенные макро операторы, которые позволяют контролировать какой именно текст будет сгенерирован в результате работы макроса
- Макросы могут принимать входящие параметры.
Чтобы иметь возможность воспользоваться макросом, его необходимо сначала определить. Пример того, как это делается, вы уже видели:
Поговорим подробнее о синтаксисе.
После оператора %macro в обязательном порядке следует имя макроса (валидное имя SAS). Затем в круглых скобках параметры. Параметров в определении макроса может и не быть. Заканчивается тело макроса всегда оператором %mend, имя макроса после ключевого слова mend – опционально, его можно не указывать, тем не менее, это считается хорошим стилем программирования.
Параметры бывают двух типов: позиционными (positional) и ключевыми (keywords). В примере выше использовались позиционные, поэтому при вызове этого макроса важнейшую роль играет то, в каком порядке будут заданы параметры.
Несколько примеров вызова этого макроса:
- %reldays(AESTDT, RFSTDT, AESTDY). Такой вызов означает, что макро переменная
date = AESTDT,
rel_date = RFSTDT,
rel_days = AESTDY - %reldays(AESTDT, AESTDY, RFSTDT). Такой вызов означает, что макро переменная
date = AESTDT,
rel_date = AESTDY,
rel_days = RFSTDT. - %reldays(AESTDT, AESTDY). Такой вызов означает, что
date = AESTDT,
rel_date = AESTDY,
rel_days = . - %reldays(AESTDT, , AESTDY). Такой вызов означает, что
date = AESTDT,
rel_date = ,
rel_days = AESTDY. - %reldays Такой вызов означает, что
date = ,
rel_date = ,
rel_days = .
Все приведенные выше варианты абсолютно допустимы и не приведут к ошибкам на этапе компиляции программы.
Ключевые параметры задаются со знаком равно после имени параметра. Например,
После знака ‘=’ можно указать «значение по-умолчанию», то есть то значение, которое будет использоваться в случае, если при вызове макроса не будет указан этот параметр. Порядок, в котором вы указываете параметры при вызове макроса, здесь не важен, поскольку вы явно указываете, какому параметру присвоить данное значение.
- %reldays(date=AESTDT, rel_days=AESTDY, rel_date=RFSTDT). Такой вызов означает, что макро переменная
date = AESTDT,
rel_date = RFSTDT,
rel_days = AESTDY - %reldays(date=AESTDT, rel_days=AESTDY). Такой вызов означает, что макро переменная
date = AESTDT,
rel_days = AESTDY,
rel_date = RFSTDT (сработало «значение по-умолчанию»). - %reldays(rel_days=AESTDY). Такой вызов означает, что
date =,
rel_days = AESTDY,
rel_days = RFSTDT. - %reldays(AESTDT). Такой вызов приведет к ошибке, поскольку при определении макроса позиционных параметров не было объявлено.
При объявлении макроса часть параметров могут быть позиционными, а часть ключевыми. Самое главное, что при этом нужно помнить, – это то, что сначала должны быть перечислены все позиционные параметры, а потом все ключевые. Например,
Тут у нас один параметр (date) – позиционный, а два последующих (rel_date и rel_days) – ключевые. При вызове этого макроса первым всегда должно идти значение для параметра date. Например, вызов %reldays( , rel_days=AESTDY) будет корректным, а вот %reldays(rel_days=AESTDY, RFSTDT) вызовет ошибку.
Как уже было замечено ранее, макросы могут содержать некие макро операторы, которые помогают контролировать, какой текст будет сгенерирован макро процессором и подставлен на место вызова макроса.
Вот список наиболее часто используемых (полный список тут Macro Statements):
%* Macro Comment Statement
%DO Statement
%DO, Iterative Statement
%DO %UNTIL Statement
%DO %WHILE Statement
%END Statement
%GLOBAL Statement
%IF-%THEN/%ELSE Statement
%LET Statement
%LOCAL Statement
%MACRO Statement
%MEND Statement
%PUT Statement
Не так уж и много, как может показаться, тем не менее, этих операторов, в купе с макро функциями, достаточно для большинства макросов.
С операторами %GLOBAL, %LET, %LOCAL, %MACRO, %MEND, %PUT вы уже знакомы.
С операторами %DO, %DO %UNTIL, %DO %WHILE, %END, %IF-%THEN/%ELSE познакомиться не сложно, поскольку они аналогичны тем же операторам из SAS BASE. Важнее всего понять, чем они отличаются от обычных, и когда ими пользоваться.
Усовершенствуем наш макрос reldays так, чтобы можно было ним пользоваться и для строковых переменных-дат.
Итак, начнем с самого начала.
%macro reldays_iso(date, rel_date, rel_days, dates_iso=1);
Новый макрос reldays_iso имеет 4 параметра: первые три – позиционные (как было и раньше), и четвертый, новый, dates_iso – отвечает за то, с датами какого типа будет работать макрос. По умолчанию задано значение 1, что соответствует тому, что даты &date, &rel_date являются строковыми переменными в формате iso.
Работа макроса основана на том, что в зависимости от значения параметра dates_iso мы задаём значения для новых локальных макро переменных &date_num и &rel_date_num, и считаем дни известным нам способом.
Какие же значения могут принимать эти новые макро переменные?
Если мы работаем с числовыми датами, то есть &dates_iso ne 1, то новые макро переменные будут просто равны тем, что пользователь макроса передал в качестве параметра:
%let date_num = &date;
%let rel_date_num = &rel_date;
Если же пользователь передает в качестве параметров строковые переменные с датами в формате iso и не забывает при этом задать dates_iso=1, то в датасете будут созданы новые числовые переменные, date_num и rel_date_num, которые будут хранить в себе числовой эквивалент строковых дат. Имена этих новых числовых переменных будут присвоены локальным макро переменным &date_num и &rel_date_num:
Таким образом, определив значения макро переменных &date_num и &rel_date_num, становится возможным выполнить оставшийся код, &rel_days = &date_num - &rel_date_num + (&date_num >= &rel_date_num);
Читайте также: