У меня была причина обрабатывать различные переменные данного набора данных с использованием повторяющегося процесса. Чтобы решить эту проблему, я написал макрос, вход которого был бы конкретной интересующей переменной. Затем макрос обработает только эту переменную. Однако оказалось, что одну из переменных нужно обрабатывать несколько иначе. Моим быстрым решением было применить условное; если переменная была исключением, выполните действие, отличное от других переменных. Проблема решена, не так ли? №Макро переменная имеет разное значение в рамках этапа DATA. Зачем?
Я нахожу, что значение макропеременной изменяется в зависимости от того, используется ли оно на шаге данных.
Пожалуйста, обратите внимание,
data example;
length dataset_var1 $ 6 dataset_var2 $ 6;
input dataset_var1 $ dataset_var2;
datalines;
value1 value2
value3 value4
;
run;
Макрос и его вызов:
%macro NoQuotes(macro_var);
%put ¯o_var. ;
data _null;
set example;
put ¯o_var. ;
if ¯o_var. = 'dataset_var1' then do;
put "The IF evaluated";
end;
else do;
put "The ELSE evaluated";
end;
run;
%put ¯o_var. ;
%mend;
%NoQuotes(dataset_var1);
Это приводит к следующей записи в журнале:
dataset_var1
value1
The ELSE evaluated
value3
The ELSE evaluated
NOTE: There were 2 observations read from the data set WORK.EXAMPLE.
NOTE: The data set WORK._NULL has 2 observations and 2 variables.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.00 seconds
dataset_var1
Обратите внимание, как значение macro_var
изменений в зависимости от независимо от того, находится ли он внутри шага DATA. Когда на этапе DATA macro_var
принимает значения dataset_var1
, то есть value1
и value3
, вместо сохранения имени dataset_var1
, как и следовало ожидать. После выхода за пределы DATA значение macro_var
волшебным образом возвращается к его правильному значению.
По предложению коллеги я разместил имя макропеременной в кавычках в условном выражении. Это заставляет условное поведение вести себя так, как ожидалось.
%macro WithQuotes(macro_var);
%put ¯o_var. ;
data _null_;
set example;
put ¯o_var. ;
if "¯o_var." = 'dataset_var1' then do;
put "The IF evaluated";
end;
else do;
put "The ELSE evaluated";
end;
run;
%put ¯o_var. ;
%mend;
%WithQuotes(dataset_var1);
Это приводит к следующей записи в журнале:
dataset_var1
value1
The IF evaluated
value3
The IF evaluated
NOTE: There were 2 observations read from the data set WORK.EXAMPLE.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
dataset_var1
Хотя условно в настоящее время выполняет, как и следовало ожидать, мы снова видим, что переменная макрос принимает значения value1
и value3
.
Поведение макропеременными кажется, противоречит всему, что я когда-либо знал о понятии переменных из BASIC, C++, Java, C#, VBA, Python, Lisp и R.
Может кто-нибудь пожалуйста объясните мне, что происходит? Я читал большую часть Macro Language Reference, но не знаю, где найти объяснения этого поведения.
Ваш ответ был неплохим до последнего предложения половины ... тот факт, что что-то вводит в заблуждение, не повод покончить с этим, когда это очень ценно. Программирование SAS без _any_ макропеременных или макросов было бы невероятно болезненным ... – Joe
Да, в некоторых случаях это может быть болезненно, сложно и невозможно, чтобы избежать макросов SAS. Тем не менее, это нетипизированный динамический язык, и в сочетании с отсутствием формальной дисциплины программирования, которую вы часто находите в магазинах SAS, это благодатный сад ошибок. – david25272