BookmarkSubscribeRSS Feed
KrisG
Calcite | Level 5
I'm trying to run a macro that looks at data at different time periods. Currently I have it looking at time periods on a continuous loop, i.e. from 1 month to 12 months. I want to be able to look at a set of specific time periods instead of a continuous list.

For example, I'd like to look at time periods 1,3,6,9,12,18,24 instead of having to run it from 1 to 24.

I'll post my code below and point out where I need it to be changed.

I know that I can do this outside of the macro language, but for the purposes of naming my data sets and identifying them later on for more analysis I believe I have to do this in a macro setting. Any help at all would be appreciated.




%macro dosql;

%do j = 0 %to 11;
%do i = 1 %to 24;

proc sql;
create table time_&j. as
select
case_nbr,
sqnc_nbr,
dflt_sts_cd,
ft_in_eps_3mnth_delq_dt,
dflt_cyc_dt
from sf.sfdw_default_history
where ft_in_eps_3mnth_delq_dt <= intnx('month',"15&m.&yr."d,&j.,'end')
and ft_in_eps_3mnth_delq_dt >= intnx('month',"15&m.&yr."d,&j., 'beginning')
order by case_nbr, sqnc_nbr;
quit;

data time_&j.;
set time_&j.;
format status $12. time.2;
status = '.';
time = '.';
run; quit;

proc sql;
create table time_&j._&i. as
select *
from time_&j.
where dflt_cyc_dt <= intnx('month',ft_in_eps_3mnth_delq_dt,&i., 'end')
order by case_nbr, sqnc_nbr;
quit;

data time_&j._&i.;
set time_&j._&i.;
by case_nbr;
if (last.case_nbr = 0) then delete;
run; quit;

data time_&j._&i.;
set time_&j._&i.;
time = "&i.";
eval_time = intnx('month',ft_in_eps_3mnth_delq_dt,&i., 'end');
format eval_time date9.;
run; quit;

data time_&j._&i.;
set time_&j._&i.;
by eval_time;
if eval_time > "&cutoff."d then delete;
run; quit;

data master_data;
set time_0 time_&j._&i.;
run; quit;

%end;
%end;
%mend;
options mprint;
%dosql;






So where it has i = 1 %to 24
I want to run it over a discrete list of numbers rather than all 24

Thanks again,

Kris G
7 REPLIES 7
Robert_Bardos
Fluorite | Level 6
This piece of code might give you an idea
[pre]
%macro doit(b=) ;
%let i = 1 ;
%do %until(%scan(&b,&i) eq) ;
%put &i %scan(&b,&i) ;
%let i = %eval(&i+1) ;
%end ;
%mend ;

%let a = 1 3 6 9 12 18 24 ;

%doit(b=&a) ;
[/pre]
KrisG
Calcite | Level 5
If i use that code provided, do i leave the references to "i" still when naming the datasets?

for example, where I name a set time_&j._&i.

Or where I have &i. listed, is there something else I have put there instead in order to have the files take on those discrete values.
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
Suggest you explore executing the code by adding the statement below which will reveal the processing logic/flow:

OPTIONS SOURCE SOURCE2 MACROGEN SYMBOLGEN MPRINT;

And consider adding MLOGIC as well.

Scott Barry
SBBWorks, Inc.
Robert_Bardos
Fluorite | Level 6
My code sample lacked a bit of clearness obviously.
In order to use the discrete values replace

%put &i %scan(&b,&i) ;

by e.g.

%let disc_i = %scan(&b,&i) ;

and use &disc_i in place of your &i.

Apply similar logic for your &j variable.

Hope this clears the mud a bit.
Robert
KrisG
Calcite | Level 5
Thank you for the help, i was able to make it work with your code.

Kris G
SUN59338
Obsidian | Level 7
in open code data step, this will work also:
data test;
do i= 1, 3, 4, 28;
output;
end;
run;
Bill
Quartz | Level 8
you could use %if &i=1 or &i=3 or &i=6 %then %do;

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


Register now!

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 7 replies
  • 3454 views
  • 0 likes
  • 5 in conversation