Hello
I have a macro called RRR
%Macro RRR(V_months);
code here
%mend RRR;
Usually I run the macro by typing the months as you see here
%RRR_STEP1(V_months=2211+2210+2209+2208+2207+2206)
%RRR_STEP1(V_months=2210+2209+2208+2207+2206+2205)
%RRR_STEP1(V_months=2209+2208+2207+2206+2205+2204)
%RRR_STEP1(V_months=2208+2207+2206+2205+2204+2203)
%RRR_STEP1(V_months=2207+2206+2205+2204+2203+2202)
%RRR_STEP1(V_months=2206+2205+2204+2203+2202+2201)
%RRR_STEP1(V_months=2205+2204+2203+2202+2201+2112)
%RRR_STEP1(V_months=2204+2203+2202+2201+2112+2111)
%RRR_STEP1(V_months=2203+2202+2201+2112+2111+2110)
%RRR_STEP1(V_months=2202+2201+2112+2111+2110+2109)
%RRR_STEP1(V_months=2201+2112+2111+2110+2109+2108)
%RRR_STEP1(V_months=2112+2111+2110+2109+2108+2107)
But it is not so comfortable to type so many dates manually.
Let's say that there is a macro var called Vector_CAT that automatically calculate the macro dates that need to run.
In this case this macro var get value : 2306+2305+2304+2303+2302+2301,2307+2306+2305+2304+2303+2302,2308+2307+2306+2305+2304+2303,2309+2308+2307+2306+2305+2304,2310+2309+23
08+2307+2306+2305
I want to run the macro multiple times
I try this code but I am not sure it is correct.
What do you think?
is it correct?
Why should I write the delimiter (comma) like this : %str(,) ?
Is there another good way to run the macro automatically from the macro varaible components?
%macro run_step1;
%do i=1 %to &n_run_step1;
%let mm = %scan(%quote(&Vector_CAT), &i, %str(,));
%RRR_STEP1(&mm);
%end;
%mend run_step1;
%run_step1;
We have already shown you how to loop over months, https://communities.sas.com/t5/SAS-Programming/calculate-macro-variables-in-structure-YYMM/m-p/95171.... Which makes me wonder why you didn't try that.
This looks like you want a moving average (or moving sum) of six months. If so, then you don't want macros at all, you want PROC EXPAND.
https://blogs.sas.com/content/iml/2016/01/27/moving-average-in-sas.html
Of course, you don't explain anything, you just jump into the code without explanation. So, please explain the purpose of this macro, without reference to code. Don't make us guess. Don't waste our time by making us figure out what you really are doing, when you already know what you really are doing and could tell us.
I agree with @PaigeMiller . It is much easier to tell us what you are getting at with your analysis. That will provide much better solutions to your problem.
But apart from that ... if you want to go forward through a comma-separated list (which is the value of a macro variable), I would do it the way below.
%LET Vector_CAT=2306+2305+2304+2303+2302+2301,2307+2306+2305+2304+2303+2302,2308+2307+2306+2305+2304+2303;
data _NULL_;
file log;
i=1;
do while ( scan("&Vector_CAT",i,",") ne " " );
currpart=trim(left(upcase(scan("&Vector_CAT",i,","))));
put currpart;
i=i+1;
end;
run;
Koen
So assuming that by your use of the word MONTH in your question we can leap to the conclusion that the four digit strings in your + delimited strings refer to dates as 4 digit strings where the digits represent the two least significant digits of the year and the two digits of the month within that year we can just use couple of nest %DO loops. To use %DO loops we will need to define a macro.
Let's also assume you want to use the same 4 digit strings as input to the new macro. So the first step should be to convert them into actual DATE values so they can be used with SAS functions that understand dates.
Each execution of the outer loop will generate one call to the existing macro. The inner loop will be used to generate the + delimited string to pass to the macro.
%macro xyz(start,stop);
%local n step i j list;
%let start=%sysfunc(inputn(&start.01,yymmdd6.));
%let stop=%sysfunc(inputn(&stop.01,yymmdd6.));
%let n=%sysfunc(intck(month,&start,&stop));
%let step=%sysfunc(sign(&n));
%do i=0 %to &n %by &step;
%let list=%sysfunc(intnx(month,&start,&i),yymmn4.);
%do j=1 %to 5;
%let list=&list+%sysfunc(intnx(month,&start,&i-&j),yymmn4.);
%end;
%RRR_STEP1(V_months=&list);
%end;
%mend xyz;
Which for your example you would call with these inputs:
%xyz(2211,2112);
Since we don't have your RRR_STEP1 macro let's replace the macro call with a %PUT
%put RRR_STEP1(V_months=&list);
so we can run it and see if it is generating the desired macro call.
Result
133 %xyz(2211,2112); RRR_STEP1(V_months=2211+2210+2209+2208+2207+2206) RRR_STEP1(V_months=2210+2209+2208+2207+2206+2205) RRR_STEP1(V_months=2209+2208+2207+2206+2205+2204) RRR_STEP1(V_months=2208+2207+2206+2205+2204+2203) RRR_STEP1(V_months=2207+2206+2205+2204+2203+2202) RRR_STEP1(V_months=2206+2205+2204+2203+2202+2201) RRR_STEP1(V_months=2205+2204+2203+2202+2201+2112) RRR_STEP1(V_months=2204+2203+2202+2201+2112+2111) RRR_STEP1(V_months=2203+2202+2201+2112+2111+2110) RRR_STEP1(V_months=2202+2201+2112+2111+2110+2109) RRR_STEP1(V_months=2201+2112+2111+2110+2109+2108) RRR_STEP1(V_months=2112+2111+2110+2109+2108+2107)
/* "MOVAVE n" = Backward moving average of n neighboring values */
proc expand data=sashelp.pricedata(drop=price1--price17 discount) out=want;
by Region Line Product;
id date;
convert sale = sale_movave / transformout=(movave 6);
convert price = price_movave / transformout=(movave 6);
convert cost = cost_movave / transformout=(movave 6);
run;
QUIT;
/* If you need more control on what exactly is happening in the */
/* transformation operation, you can use PROC TIMEDATA */
/* end of program */
You need SAS/ETS or SAS Econometrics for the above.
Ciao, Koen
@Ronein wrote:
For each set ( for example 2211 2210 2209 2208 2207 2206) need to calculate for each argument average 6 months back so for 2211 calculate average of 2211-2206 and for 2210 calculate average of 2210-2205 and so on. Please note yymm structure.
This is a moving average. As I said, you want to do this in PROC EXPAND. SAS has already programmed this for you. No need for macros. In fact, before you start coding some statistical calculation via macros, you really should check to see if SAS has a PROC that will do this. And if you don't know or can't find one, you can simply ask here in these forums if there is a SAS PROC that does the statistical calculation you want.
PS: You want to calculate the moving average for variables that contain some sort of monthly average. But you don't show variables, you show NUMBERs in your problem description. These are numbers because they are not valid variable names. Please make the data or variable names clear from now on.
So back to my other point. Please tell us what you are doing, and why you are doing it, instead of just focusing on code. And please don't make us ask for this critical information repeatedly.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.