16 апреля 2012 в 11:22

CALL SYMPUT vs CALL SYMPUTX или SAS Base для чайников из песочницы

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

CALL SYMPUT


Call Symput используется для случаев, когда значение переменной в шаге данных (datastep) нужно присвоить макропеременной.
Синтаксис: call symput ("<макропеременная>", <символьное значение>)

Первый аргумент в процедуре symput — это название макропеременной, которой необходимо присвоить значение второго аргумента.

Второй аргумент — это символьное значение, которое будет присвоено макропеременной. Второй аргумент всегда должен быть именно символьным, в противном случае, численное значение должно быть конвертировано в символьную переменную, прежде чем присваивать его макропеременной. Если Вы не станете приводить тип, это может обернуться проблемами. В таком случае SAS автоматически конвертирует численное значение переменной в символьное значение, прежде чем присвоит его макропеременной, и выведет в лог сообщение о том, что было произведено конвертирование.

Пример:
data _null_;
count=1978;
call symput('count',count);
run;
%put &count;

19 data _null_;
20 count=1978;
21 call symput('count',count);
22 run;

NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
21:21
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.01 seconds

23 %put &count;
1978


Хоть значение макропеременной count и было определено как 1978, SAS выдал замечание, гласящее
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
21:21


Чтобы избежать этого, Вам всё же стоит осуществить конвертирование численного значения в символьное, прежде чем присваивать его макропеременной. Вот, например, как это можно сделать:

data _null_;
count=1978;
call symput('count',strip(put(count,8.)));
run;
%put &count;

29 data _null_;
30 count=1978;
31 call symput('count',left(put(count,8.)));
32 run;

NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

33 %put &count;
1978


Примечания:
  1. Несмотря на то, что мы создали переменную при помощи CALL SYMPUT, эта макропеременная не может быть использована напрямую в том же datastep'е. Причина такого явления — макро код компилируется и выполняется до того, как будет скомпилирован и выполнен datastep. Так что, макропеременная, создающаяся CALL SYMPUT, не будет доступна в datastep в силу того, что эта макропеременная будет создана и присвоена только после или во время выполнения кода datastep.
    (В случае, если Вам всё же понадобится доступ к той же макропеременной внутри datastep, Вы, разумеется, сумеете это сделать, при помощи двух разных макрофункций — RESOLVE или SYMGET)
  2. SAS всегда выравнивает численные значения по правому краю, что приводит к пробелам в начале символьной переменной при конвертации, если значение численной переменной было меньше её длины. Чтобы избавиться от этих пробелов, используйте функции, удаляющие все ведущие пробелы (как в примере выше).
  3. Если процедура CALL SYMPUT используется вне макроса (т.е. в открытом коде), она создаёт глобальную макропеременную, тогда как при использовании внутри макроса она создаст локальную.


CALL SYMPUTX


Процедура CALL SYMPUTX была анонсирована SAS в 9 версии с целью обойти ловушки CALL SYMPUT.
Преимущества CALL SYMPUTX перед CALL SYMPUT включают в себя:
  1. SYMPUTX автоматически конвертируют численные переменные в символьные перед присваиванием их макропеременной. (Вы больше не нуждаетесь в ручной конвертации при помощи выраждения PUT как в вышеприведённом примере)
  2. CALL SYMPUTX удаляет ведущие и хвостовые пробелы. Так что необходимость функций, наподобие STRIP или LEFT, для очистки от лишних пробелов, отпадает.

Синтаксис: call symputx ("<макропеременная>", <символьное значение>, <таблица символов>)

Первые два аргумента аналогичны аргументам CALL SYMPUT. Третий аргумент (таблица символов) опционален и может принимать значения G, L или F. Если Вы укажете G, макропеременная будет создана в глобальной таблице символов, если же Вы укажете L, SAS сохранит макропеременную в локальной таблице. Если третий аргумент не указывать или установить его как F, CALL SYMPUTX будет вести себя аналогично CALL SYMPUT.

Пример:
data _null_;
count=1978;
call symputx('count',count,’G’);
run;
%put &count;

29 data _null_;
30 count=1978;
31 call symputx('count',count,'G');
32 run;

NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

33 %put &count;
1978

Примечание: Если бы Вы использовали CALL SYMPUT вместо CALL SYMPUTX, программа выполнилась бы идентично, но в лог было бы выдано замечание об автоматической конвертации численного значения в символьное.

Простой способ запомнить разницу между CALL SYMPUT и CALL SYMPUTX:
(взято со страницы Using_the_SAS_V9_CALL_SYMPUTX_Routine на SAScommunity.org)

Процедура SAS V9 CALL SYMPUTX позволяет Вам сэкономить нажатия клавиш и создать более компактный и понятный код.
Вместо использования
call symput('macrovar', trim(left(charvar)));
для создания макропеременной с символьной строкой, которая может содержать лишние пробелы, Вам стоит применить SYMPUTX:
call symputx('macrovar', charvar);
+1
748
3

Комментарии (0)

Только зарегистрированные пользователи могут оставлять комментарии.
Войдите, пожалуйста.