Вы хотите l oop в течение ряда дат во входном наборе данных. Поэтому я использую оператор PROC SQL
, в котором я выбираю различные даты в этом наборе входных данных в макропеременную. Эта макропеременная затем используется для l oop over. Таким образом, в вашем примере макропеременная будет: 20200428 20200429
. Затем вы можете использовать макрофункцию %SCAN
, чтобы начать цикл по этим датам.
Для каждой даты в l oop мы затем вычислим среднее значение: в вашем примере среднее значение за 3 дня до даты цикла. Поскольку число дней, за которое вы хотите рассчитать среднее значение, является переменным, оно также передается в качестве параметра в макрос. Затем я использую INTNX function
, чтобы вычислить нижнюю границу дат, которые вы хотите выбрать для расчета среднего значения. Затем для вычисления среднего объема по дням используется процедура PROC MEANS
: нижняя граница - дата цикла.
Затем я помещаю небольшой шаг данных между ними, чтобы снова прикрепить дату цикла к вычисленному среднему значению. Наконец, все добавляется в окончательный набор данных.
%macro dayAverage(input = , range = , selectiondata = );
/* Input = input dataset
range = number of days prior to the selected date for which you want to calculate
the average
selectiondata = data where the volumes are in */
/* Create a macro variable with the dates for which you want to calculate the
average, to loop over */
proc sql noprint;
select distinct date into: datesrange separated by " "
from &input.;
quit;
/*Start looping over the dates for which you want to calculate the average */
%let I = 1;
%do %while (%scan(&datesrange.,&I.) ne %str());
/* Assign the current date in the loop to the variable currentdate */
%let currentdate = %scan(&datesrange.,&I.);
/* Create the minimum date in the range based on input parameter range */
%let mindate =
%sysfunc(putn(%sysfunc(intnx(day,%sysfunc(inputn(¤tdate.,yymmdd8.)),-
&range.)),yymmddn8.));
/* Calculate the mean volume for the selected date and selected range */
proc means data = &selectiondata.(where = (date >= &mindate. and date <
¤tdate.)) noprint ;
output out = averagecurrent(drop = _type_ _freq_) mean(volume)=avgerage_volume;
run;
/* Add the current date to the calculated average */
data averagecurrent;
retain date average_volume;
set averagecurrent;
date = ¤tdate.;
run;
/* Append the result to a final list */
proc datasets nolist;
append base = final data = averagecurrent force;
run;
%let I = %eval(&I. + 1);
%end;
%mend;
Этот макрос в вашем примере можно назвать так:
%dayAverage(input = event, range = 3, selectiondata = vol);
Он даст вам набор данных в вашей рабочей библиотеке, который называется final