Разрешение макропеременных в шаге данных

У меня проблемы с получением операторов If/Then для корректной работы с моими макро-переменными внутри шага данных. Я пишу макрос для обработки двух разных случаев: вычисление статистических тестов без преобразования, а затем вычисление статистических тестов после естественного преобразования журнала. Если мои данные не проходят проверку нормальности, я регистрирую преобразование и проверяю снова. Если это пройдет, я установлю свой глобальный флаг, log_flag, к 1. Затем я хочу проверить состояние этого флага в шагах данных, чтобы правильно обрабатывать преобразованные (или нет) переменные. Я пробовал варианты следующего:

Data want;
set have;
if symget("log_flag")=1 then do;
if &log_flag. = 1 then do;
if resolve("log_flag")=1 then do;
test=symget("log_flag");
  if test=1 then do;
end

Что бы я ни пытался, оператор if / then по существу игнорируется, и весь следующий за ним код обрабатывается так, как если бы if / then было истинным, даже когда оно ложно. Я знаю что log_flag правильно присваивается значение ноль, потому что %if%then операторы работают и правильно выполняются в открытом коде. У меня просто проблемы с получением правильного разрешения внутри шага данных.

Пожалуйста, дайте мне знать, если вам нужна какая-то другая информация, чтобы помочь мне разобраться в этом. Спасибо, парни!

2 ответа

Решение
  • SYMGET() вернет символьную переменную.
  • RESOLVE () вернет символьную переменную, но для нее требуется параметр &.
  • & log_flag будет преобразован в число

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

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

%let log_flag=1;
Data want;
set sashelp.class;
if symget("log_flag")='1' then do;
  put "Test #1 is True";
end;

if &log_flag. = 1 then do;
  put "Test #2 is True";
end;


if resolve("&log_flag")="1" then do;
  put "Test #3 is True";
end;

test=symget("log_flag");
if test='1' then do;
  put "Test #4 is True";
end;

run;

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

Так что если вы хотите создать переменную newvar когда макропеременная log_flag один, то вы могли бы написать это таким образом.

data want ;
  set have ;
%if &log_flag. = 1 %then %do;
  newvar= x*y ;
%end;
run;

Так когда &log_flag. = 1 вы запускаете этот код:

data want ;
  set have ;
  newvar= x*y ;
run;

И когда это не так, вы запускаете этот код:

data want ;
  set have ;
run;

Начиная с версии SAS 9.4 M5 вы можете использовать это в открытом коде, в противном случае поместите его в определение макроса и выполните макрос.

Другие вопросы по тегам