Looking to create a &year macro that will increment by year for 2013-2016
So my datasets for 2013 to 2016 can be named as such:
new_data_&year:
new_data_2013
new_data_2014
new_data_2015
new_data_2016
%macro _year_inc (Y_start, Y_end);
%do year= &Y_start %to &Y_end;
data new_data_&year;
run;
%end;
%mend;
%_year_inc(2013,2016)
%macro _year_inc (Y_start, Y_end);
%do year= &Y_start %to &Y_end;
data new_data_&year;
run;
%end;
%mend;
%_year_inc(2013,2016)
Hi @AP718
You're welcome
Hi @AP718
Another approach could be :
data _null_;
do year = 2013 to 2016;
rc = dosubl(cats('data new2_data_',year,';run;'));
output;
end;
run;
-> the DOSUBL function enables the immediate execution of code.
Best,
Hi @ed_sas_member ,
One remark about DoSubL() function. Considering all of it's advantages there is one significant disadvantage - speed. If you consider the following code:
%let t=%sysfunc(time());
data _null_;
do year = 2001 to 2010;
rc = dosubl(cats('data new2_data_',year,';run;'));
output;
end;
run;
%put %sysevalf(%sysfunc(time()) - &t.);
%let t=%sysfunc(time());
%macro _year_inc (Y_start, Y_end);
%do year= &Y_start %to &Y_end;
data new_data_&year;
run;
%end;
%mend;
%_year_inc(1901,1910)
%put %sysevalf(%sysfunc(time()) - &t.);
you can see that it was much longer for dosubl() to generate (only) 10 datasets, the log:
1 2 %let t=%sysfunc(time()); 3 data _null_; 4 do year = 2001 to 2010; 5 rc = dosubl(cats('data new2_data_',year,';run;')); 6 output; 7 end; 8 run; NOTE: The data set WORK.NEW2_DATA_2001 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW2_DATA_2002 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW2_DATA_2003 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW2_DATA_2004 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW2_DATA_2005 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW2_DATA_2006 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.00 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW2_DATA_2007 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW2_DATA_2008 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW2_DATA_2009 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW2_DATA_2010 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: DATA statement used (Total process time): real time 13.85 seconds cpu time 8.86 seconds 9 %put %sysevalf(%sysfunc(time()) - &t.); 13.8770000934018 10 11 %let t=%sysfunc(time()); 12 %macro _year_inc (Y_start, Y_end); 13 %do year= &Y_start %to &Y_end; 14 data new_data_&year; 15 run; 16 %end; 17 %mend; 18 19 %_year_inc(1901,1910) NOTE: The data set WORK.NEW_DATA_1901 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.02 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW_DATA_1902 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.03 seconds NOTE: The data set WORK.NEW_DATA_1903 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.03 seconds NOTE: The data set WORK.NEW_DATA_1904 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW_DATA_1905 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.02 seconds cpu time 0.03 seconds NOTE: The data set WORK.NEW_DATA_1906 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.02 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW_DATA_1907 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.02 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW_DATA_1908 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW_DATA_1909 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.02 seconds cpu time 0.01 seconds NOTE: The data set WORK.NEW_DATA_1910 has 1 observations and 0 variables. NOTE: DATA statement used (Total process time): real time 0.02 seconds cpu time 0.01 seconds 20 %put %sysevalf(%sysfunc(time()) - &t.); 0.39300012589956
So it is 13.8770000934018 seconds for DoSubL() vs. 0.39300012589956 for macro.
In general I think it is better to avoid looping over DoSubL(). In short words:
DoSubL(with loop inside) - good practice
Loop over DoSubL() - bad practice
In our case I think Call Execute() would be more robust:
%let t=%sysfunc(time());
data _null_;
do year = 1801 to 1810;
call execute(cats('data new3_data_',year,';run;'));
end;
run;
%put %sysevalf(%sysfunc(time()) - &t.);
With timing: 0.39300012589956 [EDIT] 0.47200012209941 seconds
All the best
Bart
Hi @yabwon
I have not had the opportunity to use dosubl / call execute on large amount of data, so thank you for the clarification!
Best,
Hi,
How can I create a macro variable for the prior year, current year and future year. The prior year will be the current year minus one year, future year will be the current year plus one year. So it will look something like this
%let cy= 2020
%let fy = &cy+1 (2021)
%let py = &cy-1 (2019)
Thanks!
Remember to put semi-colons on the end of your SAS commands!
%let cy= 2020;
%let fy = %eval(&cy+1);
%let py = %eval(&cy-1);
Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!
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.