Привязка глобальной макропеременной шага данных к процедурному процессу в SAS

#sas #global-variables

#sas #глобальные переменные

Вопрос:

Я хочу использовать переменные из моего списка в процедурах proc. Вот упрощенная версия моего кода.

 %MACRO CORRMAKER(file,data);
%DO I=1 %TO 2;
%DO J=1 %TO 2;

data _NULL_;
ARRAY VAR1LIST[2] $ A1-A2 ('CAT11' 'CAT12');
ARRAY VAR2LIST[2] $ B1-B2 ('CAT21' 'CAT22');

%GLOBAL VAR1 VAR2;
%LET VAR1=VAR1LIST[amp;I];
%LET VAR2=VAR2LIST[amp;J];
run;

proc corr data=amp;file out=amp;dataamp;Iamp;J RANK noprob;
var INNERVAR1 INNERVAR2 INNERVAR3 INNERVAR4;
where COND1=amp;VAR1 COND2=amp;VAR2;
run;

%END;
%END;
%MEND;
  

Но VAR1 и VAR2 не имеют в proc соответствующей процедуры. Как я могу использовать VAR1 и VAR2?

Спасибо!

Комментарии:

1. Подсказка: это недопустимый оператор WHERE: where cond1=VAR1LIST[1]

Ответ №1:

Я не уверен, почему вы делаете VAR1 и VAR2 глобальными, а не локальными. Похоже, что они имеют значение только внутри этого макроса. В конце макроса им просто будет присвоено последнее значение внутри %do циклов.

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

 %LET VAR1=VAR1LIST[amp;I];
%LET VAR2=VAR2LIST[amp;J];

data _NULL_;
ARRAY VAR1LIST[2] $ A1-A2 ('CAT11' 'CAT12');
ARRAY VAR2LIST[2] $ B1-B2 ('CAT21' 'CAT22');
run;
  

Если вы действительно хотите использовать имена переменных CAT11, CAT21 и т.д., То просто создайте их из I и J.

 %let var1=cat1amp;i;
%let var2=cat2amp;j;
  

Если у вас действительно есть списки имен переменных, поместите списки в макропеременные.

 %let varlist1=cat11 cat12;
%let varlist2=cat21 cat22;
%let var1=%scan(amp;varlist1,amp;i);
%let var2=%scan(amp;varlsit2,amp;j);
  

Ваш оператор WHERE также выглядит неправильно. Возможно, вы имели в виду что-то более похожее:

 %let values1 = cat11 cat12 ;
%let values2 = cat21 cat22 ;
%do i=1 %to 2 ;
%do j=1 %to 2 ;
  ....
  where cond1="%scan(amp;values1,amp;i)" and cond2="%scan(amp;values2,amp;j)";
  ....
%end;
%end;
  

Комментарии:

1. Большое вам спасибо! На самом деле, мой VAR1LIST состоит из массива chacter типа (‘cat’, ‘dog’, ‘horse’), которые не представлены в виде текста чисел. Мне следовало спросить более конкретно, и вы любезно ожидали моей ситуации. Как вы сказали, это не было проблемой глобальной переменной. Спасибо!

Ответ №2:

Макросы не имеют собственной конструкции массива. Термин «массив макросов» является метафорой для случая области, имеющей доступ к N макропеременным с одинаковым базовым именем и последовательными (или индексными) суффиксами. Вы можете напрямую назначить каждой переменной, которая действует как элемент массива, или у вас может быть какой-нибудь изящный код, который выделяет переменные из текстового списка.

«Индексированные» переменные разрешаются в цикле с использованием конструкции amp;amp;amp;. Например:

 %let A2 = 1234;
%let index = 2;

%let var1 = amp;amp;Aamp;index;       %* var1 gets 1234;
  

Часть обязанностей супервизоров SAS заключается в неявном разрешении макроображений, повторяя токен по мере необходимости. Удвоенные значения amp; ‘s уменьшаются вдвое на каждой итерации неявного разрешения. Например:

 amp;amp;Aamp;index -> amp;A2 -> 1234
  

Ваш код может измениться на

 %MACRO CORRMAKER(file,data);

  %local A1 A2 B1 B2 I J VAR1 VAR2;

  %let A1 = CAT11;
  %let A2 = CAT12;

  %let B1 = CAT21;
  %let B2 = CAT22;

  %DO I=1 %TO 2;
  %DO J=1 %TO 2;

    %LET VAR1=amp;amp;Aamp;I;
    %LET VAR2=amp;amp;Bamp;J;

    proc corr data=amp;file out=amp;dataamp;Iamp;J RANK noprob;
      var INNERVAR1 INNERVAR2 INNERVAR3 INNERVAR4;
      where COND1="amp;VAR1" and COND2="amp;VAR2";
    run;
  %END;
  %END;

%MEND;
  

Комментарии:

1. На самом деле, у меня есть реальный список переменных, которые не представлены в виде текста числа. Мне следовало спросить более конкретно. Но ваш ответ очень помог мне понять структуру макросов SAS. Спасибо!