I am trying to automate a process in SAS that alters the value of a variable in a dataset iteratively and calculates another variable for each. I am trying to get that to work as a macro within a loop, where the parameters in the inner Macro are taken as the start and end of the do loop.
So that would look like:
%Macro Outer (variable, dataset, output, i,j);
proc sql noprint;
Create table &Variable._stats as
Select *,
min(Variable) as &Variable._min,
max(Variable) as &Variable._max,
range(Variable) as &Variable._range
From &dataset;
%do &i %to &j;
%Macro Inner (Variable, dataset, output, &&i(???), &&j(????))
data &output;
&Variable._stats;
&Variable._2 = &Variable - (Variable._range)*&&i/&&j;
If &Variable._2 > &Variable._max then &Variable._2 = &Variable._max;
If &Variable._2 > &Variable._min then &Variable._2 = &Variable._min;
iteration = &&i;
run;
%Mend Inner;
%Mend Outer;
I will be adding more stuff to it, afterwards, but for the time being, I'm trying to ascertain the correct syntax and whether its appropriate to have the counter values from the loop be the parameters for the inner macro and how to use them in the datastep.
If really want to have two macros, you can implement inner
macro before outer
, and inside loop just call inner
macro with parameters,that you need. And you forgot about set
statement in data step and %end
statement. Below i try to describe this idea, but without data samples it's hard.
%Macro Inner (Variable, dataset, output, i, j);
data &output;
set &Variable._stats;
&Variable._2 = &Variable - (Variable._range)*&i/&j;
If &Variable._2 > &Variable._max then &Variable._2 = &Variable._max;
If &Variable._2 > &Variable._min then &Variable._2 = &Variable._min;
iteration = &i;
run;
%Mend Inner;
%Macro Outer (variable, dataset, output, i,j);
proc sql noprint;
Create table &Variable._stats as
Select *,
min(&Variable) as &Variable._min,
max(&Variable) as &Variable._max,
range(&Variable) as &Variable._range
From &dataset;
quit;
%do p=&i %to &j;
%inner(&variable,&dataset,&output,&i,&j);
%end;
%Mend Outer;
But if i understand correctly, better to use one macro:
%Macro Outer (variable, dataset, output, i,j);
proc sql noprint;
Create table &Variable._stats as
Select *,
min(&Variable) as &Variable._min,
max(&Variable) as &Variable._max,
range(&Variable) as &Variable._range
From &dataset;
quit;
%do p=&i %to &j;
data &output;
set &Variable._stats;
&Variable._2 = &Variable - (Variable._range)*&i/&j;
If &Variable._2 > &Variable._max then &Variable._2 = &Variable._max;
If &Variable._2 > &Variable._min then &Variable._2 = &Variable._min;
iteration = &i;
run;
%end;
%Mend Outer;