SAS вызывает symput в шаге данных - PullRequest
0 голосов
/ 05 февраля 2019

Я столкнулся с этой проблемой с шагом данных sas.Мое требование - получить список переменных, таких как

total_jun2018 = sum(jun2018, dep_jun2018);
total_jul2018 = sum(jul2018, dep_jul2018);

Data final4;
set final3;
by hh_no;

do i=0 to &tot_bal_mnth.;
  bal_mnth =  put(intnx('month',"&min_Completed_dt."d, i-1), monyy7.);
  call symputx('bal_mnth', bal_mnth);
  &bal_mnth._total=sum(&bal_mnth., Dep_&bal_mnth.);
  output;
end;

Но я сталкиваюсь с ошибкой, что макропеременная bal_mnth не разрешена.Кроме того, после успешного запуска, но я хочу, чтобы вывод выводился последовательно, а вывод только для последнего цикла, когда i=6, затем выводится только Total_DEC2018=sum(DEC2018, DEP_DEC2018);

. Любая помощь приветствуется!

Спасибо, Аджай

Ответы [ 3 ]

0 голосов
/ 05 февраля 2019

Похоже, вы хотите сгенерировать серию операторов присваивания, таких как:

total_jun2018 = sum(jun2018, dep_jun2018); 
total_jul2018 = sum(jul2018, dep_jul2018);
...
total_jan2019 = sum(jan2019, dep_jan2019);

То, что известно как обои код.

Если имена переменных былипроще, например, от dep1 до dep18, тогда было бы легко использовать массивы для обработки данных.С вашим текущим соглашением об именах проблема с генерацией операторов массива мало чем отличается от проблемы генерации серии операторов присваивания.

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

%local i bal_mnth;
%do i=0 %to &tot_bal_mnth.;
  %let bal_mnth =  %sysfunc(intnx(month,"&min_Completed_dt."d, &i-1), monyy7.);
  total_&bal_mnth = sum(&bal_mnth , Dep_&bal_mnth );
%end;

Или вы можете просто сгенерировать код в файл с шагом данных.

%let tot_bal_mnth = 7;
%let min_Completed_dt=01JUN2018;
filename code temp;
data _null_;
  file code;
  length bal_mnth $7 ;
  do i=0 to &tot_bal_mnth.;
    bal_mnth =  put(intnx('month',"&min_Completed_dt."d, i-1), monyy7.);
    put 'total_'  bal_mnth $7. ' = sum(' bal_mnth $7. ', Dep_' bal_mnth $7. ');';
  end;
run;

Таким образом, сгенерированный файл кода выглядит следующим образом:

total_MAY2018 = sum(MAY2018, Dep_MAY2018);
total_JUN2018 = sum(JUN2018, Dep_JUN2018);
total_JUL2018 = sum(JUL2018, Dep_JUL2018);
total_AUG2018 = sum(AUG2018, Dep_AUG2018);
total_SEP2018 = sum(SEP2018, Dep_SEP2018);
total_OCT2018 = sum(OCT2018, Dep_OCT2018);
total_NOV2018 = sum(NOV2018, Dep_NOV2018);
total_DEC2018 = sum(DEC2018, Dep_DEC2018);

Затем вы можете использовать %include, чтобы запустить его на шаге данных.

data final4;
  set final3;
  by hh_no;
  %include code / source2 ;
run;
0 голосов
/ 05 февраля 2019

Я хотел бы предложить другую точку зрения: трудности, с которыми вы здесь сталкиваетесь, связаны с использованием широкой формы данных с большим количеством столбцов.

Вместо того, чтобы работать с вашими данными в этой форме,Вы могли бы сначала перенести с широкого на длинный, чтобы вместо множества total_xxx столбцов у вас было только 3: total, total_dep и date, с одной строкой в ​​месяц.Как только он будет в этом формате, с ним будет намного легче работать, что потенциально позволит вам не прибегать к макросам и коду обоев.

Рекомендуемое чтение:

Транспонировать от широких до длинных сдинамические переменные

0 голосов
/ 05 февраля 2019

Это распространенная проблема при изучении SAS Macro.Проблема состоит в том, что макропроцессору необходимо разрешить &bal_mnth в значение, когда шаг данных впервые передается на выполнение, но СИМПУТ ВЫЗОВА не выполняется до тех пор, пока шаг данных не будет фактически выполнен, поэтому во время отправки кода, значение &bal_mnth.

недоступно. В этом случае вам не нужно создавать bal_mnth в качестве переменной в наборе данных, поэтому вы можете заменить строку, начинающуюся bal_mnth = put(intck(...))с %let bal_mnth = ... заявлением.%let выполняется во время отправки шага данных, поэтому его значение будет доступно, когда вам это нужно.

Мой предложенный оператор %let должен будет обернуть функции хотя бы в один SYSFUNC вызов, который оставляется в качестве упражнения для читателя: -)

...