Всем привет!
Данная статья - это голая калька с другой статьи.
К сожалению, на
habrahabr.ru
нету как такого раздела или публикаций на тему SAS. И искать там
что-либо оказывается затруднительным, если не знаешь, что искать =)
Данный же ресурс целиком и полностью предназначен для SAS пользователей.
Краткая предыстория проблемы, решение которой пришлось сначала искать самому.
Задача считать название файлов из директории и записать их в другую директорию.
filename read1 ftp '' ls lsfile='*.txt' cd="" &ftp;
data read1;
length name $ 60;
infile read1;
input name $;
run;
Тут возникает вопрос, как записать значение данной переменной в макропеременную так, чтобы обрезать хвост. Не стану вдаваться в подробности какие способы были использованы для решения данной проблемы, а вставлю текст, который сразу всё расставит на свои места.
Источник
http://habrahabr.ru/post/142147/
За что автору большой плюс в его карму! =)
===============================================================
Добрый день, дорогие читатели.
В этой статье я расскажу о двух процедурах языка 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
Примечания:
- Несмотря на то, что мы создали переменную при помощи
CALL SYMPUT
,
эта макропеременная не может быть использована напрямую в том же
datastep'е. Причина такого явления — макро код компилируется и
выполняется до того, как будет скомпилирован и выполнен datastep. Так
что, макропеременная, создающаяся CALL SYMPUT
, не будет
доступна в datastep в силу того, что эта макропеременная будет создана и
присвоена только после или во время выполнения кода datastep.
(В случае, если Вам всё же понадобится доступ к той же макропеременной
внутри datastep, Вы, разумеется, сумеете это сделать, при помощи двух
разных макрофункций — RESOLVE
или SYMGET
)
- SAS всегда выравнивает численные значения по правому краю, что
приводит к пробелам в начале символьной переменной при конвертации, если
значение численной переменной было меньше её длины. Чтобы избавиться от
этих пробелов, используйте функции, удаляющие все ведущие пробелы (как в
примере выше).
- Если процедура
CALL SYMPUT
используется вне макроса
(т.е. в открытом коде), она создаёт глобальную макропеременную, тогда
как при использовании внутри макроса она создаст локальную.
CALL SYMPUTX
Процедура CALL SYMPUTX
была анонсирована SAS в 9 версии с целью обойти ловушки CALL SYMPUT
.
Преимущества CALL SYMPUTX
перед CALL SYMPUT
включают в себя:
SYMPUTX
автоматически конвертируют численные переменные
в символьные перед присваиванием их макропеременной. (Вы больше не
нуждаетесь в ручной конвертации при помощи выраждения PUT как в
вышеприведённом примере)
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);