BookmarkSubscribeRSS Feed
Yamani
Obsidian | Level 7

Hello All,

 

I am using the following Macro code:

 

%MACRO rollingreg
(data=mom12.developing, out_ds=results,
id=country, date=date,
model_equation= RETURN = MOM,
start_date= 12-31-1996, end_date= 12-31-2014,
freq=month, s=1, n=36,
regprint=noprint);

%* Start with empty output data sets;
proc datasets nolist;
delete _all_ds _outest_ds;
run;

* Prepare input data for by-id-date use;
proc sort data=&data;
by &id &date;
run;

%* Set the 'by-id' variable;
%if &year_date=1 %then %let freq=year;
%* year frequency case;
%put Date variable: &date year_date: &year_date;
%put Start and end dates: &start_date &end_date // &sdate1 &sdate2;
%if &year_date=0 %then
%put %sysfunc(putn(&sdate1,date9.)) %sysfunc(putn(&sdate2,date9.));
%put Freq: &freq s: &s n: &n;

%* Preliminary date setting for each iteration/loop;
%* First end date (idate2) is n periods after the start date;
%if &year_date=1 %then %let idate2= %eval(&sdate1+(&n-1));
%else %let idate2= %sysfunc(intnx(&freq,&sdate1,(&n-1),end));
%if &year_date=0 %then %let idate1= %sysfunc(intnx(&freq,&idate2,-&n+1,begin));
%else %let idate1= %eval(&idate2-&n+1);
%put First loop: &idate1 -- &idate2;
%put Loop through: &sdate2;
%if (&idate2 > &sdate2) %then %do;

%* Dates are not acceptable-- show problem, do not run loop;
%put PROBLEM-- end date for loop exceeds range : ( &idate2 > &sdate2 );
%end;
%else %do; *Dates are accepted-- run loops;
%let jj=0;
%do %while(&idate2 <= &sdate2);
%let jj=%eval(&jj+1);

%*Define loop start date (idate1) based on inherited end date (idate2);
%if &year_date=0 %then %do;
%let idate1= %sysfunc(intnx(&freq,&idate2,-&n+1,begin));
%let date1c= %sysfunc(putn(&idate1,date9.));
%let date2c= %sysfunc(putn(&idate2,date9.));
%end;
%if &year_date=1 %then %do;
%let idate1= %eval(&idate2-&n+1);
%let date1c= &idate1;
%let date2c= &idate2;
%end;
%let idate1= %sysfunc(max(&sdate1,&idate1));
%put Loop: &jj -- &date1c &date2c;
%put &jj -- &idate1 &idate2;
proc datasets nolist;
delete _outest_ds;
run;

%***** analysis code here -- for each loop;
%* noprint to just make output set;
%let noprint= noprint;
%if %upcase(®print) = yes | %upcase(®print) = print %then %let noprint= ;
proc reg data=&data
outest=_outest_ds edf
&noprint;
where &date between &idate1 and &idate2;
model &model_equation;
&by_id;
run;

%* Add loop date range variables to output set;
data _outest_ds;
set _outest_ds;
regobs= _p_ + _edf_; %* number of observations in regression;
date1= &idate1;
date2= &idate2;
%if &year_date=0 %then format date1 date2 date9.;
run;
%* Append results;
proc datasets nolist;
append base=_all_ds data=_outest_ds;
run;

%* Set next loop end date;
%if &year_date=0 %then %let idate2= %sysfunc(intnx(&freq,&idate2,&s,end));
%else %if &year_date=1 %then %let idate2= %eval(&idate2+&s);
%end; *% end of loop;
%* Save outout set to desired location;
data &out_ds;
set _all_ds;
run;
proc sort data=&out_ds;
by &id date2;
run;
%end; %* end for date check pass section;
%mend;
%rollingreg;

 

 

However, whenever I run the above code, I see the following error message:

WARNING: Apparent symbolic reference YEAR_DATE not resolved.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric
operand is required. The condition was: &year_date=1
ERROR: The macro ROLLINGREG will stop executing.

4 REPLIES 4
WarrenKuhfeld
Rhodochrosite | Level 12

This is the first place that macro variable appears.

%if &year_date=1 %then %let freq=year;

It has not been set to a value before you used it.

 

Your code would be easier to look at if you use the insert SAS code "run box" when you paste it.

Reeza
Super User

Format the code so it's legible as well. The indents help you find errors and a wall of code is difficult to parse.

 

%MACRO rollingreg
			(data=mom12.developing, out_ds=results,
			id=country, date=date,
			model_equation= RETURN = MOM,
			start_date= 12-31-1996, end_date= 12-31-2014,
			freq=month, s=1, n=36,
			regprint=noprint);
	%* Start with empty output data sets;
	proc datasets nolist;
		delete _all_ds _outest_ds;
	run;

	* Prepare input data for by-id-date use;
	proc sort data=&data;
		by &id &date;
	run;

	%* Set the 'by-id' variable;
	%if &year_date=1 %then
		%let freq=year;

	%* year frequency case;
	%put Date variable: &date year_date: &year_date;
	%put Start and end dates: &start_date &end_date // &sdate1 &sdate2;

	%if &year_date=0 %then
		%put %sysfunc(putn(&sdate1,date9.)) %sysfunc(putn(&sdate2,date9.));
	%put Freq: &freq s: &s n: &n;

	%* Preliminary date setting for each iteration/loop;
	%* First end date (idate2) is n periods after the start date;
	%if &year_date=1 %then
		%let idate2= %eval(&sdate1+(&n-1));
	%else %let idate2= %sysfunc(intnx(&freq,&sdate1,(&n-1),end));

	%if &year_date=0 %then
		%let idate1= %sysfunc(intnx(&freq,&idate2,-&n+1,begin));
	%else %let idate1= %eval(&idate2-&n+1);
	%put First loop: &idate1 -- &idate2;
	%put Loop through: &sdate2;

	%if (&idate2 > &sdate2) %then
		%do;
			%* Dates are not acceptable-- show problem, do not run loop;
			%put PROBLEM-- end date for loop exceeds range : ( &idate2 > &sdate2 );
		%end;
	%else
		%do;
			*Dates are accepted-- run loops;
			%let jj=0;

			%do %while(&idate2 <= &sdate2);
				%let jj=%eval(&jj+1);

				%*Define loop start date (idate1) based on inherited end date (idate2);
				%if &year_date=0 %then
					%do;
						%let idate1= %sysfunc(intnx(&freq,&idate2,-&n+1,begin));
						%let date1c= %sysfunc(putn(&idate1,date9.));
						%let date2c= %sysfunc(putn(&idate2,date9.));
					%end;

				%if &year_date=1 %then
					%do;
						%let idate1= %eval(&idate2-&n+1);
						%let date1c= &idate1;
						%let date2c= &idate2;
					%end;

				%let idate1= %sysfunc(max(&sdate1,&idate1));
				%put Loop: &jj -- &date1c &date2c;
				%put &jj -- &idate1 &idate2;

				proc datasets nolist;
					delete _outest_ds;
				run;

				%***** analysis code here -- for each loop;
				%* noprint to just make output set;
				%let noprint= noprint;

				%if %upcase(®print) = yes | %upcase(®print) = print %then
					%let noprint=;

				proc reg data=&data
					outest=_outest_ds edf
					&noprint;
					where &date between &idate1 and &idate2;
					model &model_equation;
					&by_id;
				run;

				%* Add loop date range variables to output set;
				data _outest_ds;
					set _outest_ds;
					regobs= _p_ + _edf_;

					%* number of observations in regression;
					date1= &idate1;
					date2= &idate2;

					%if &year_date=0 %then
						format date1 date2 date9.;
				run;

				%* Append results;
				proc datasets nolist;
					append base=_all_ds data=_outest_ds;
				run;

				%* Set next loop end date;
				%if &year_date=0 %then
					%let idate2= %sysfunc(intnx(&freq,&idate2,&s,end));
				%else %if &year_date=1 %then
					%let idate2= %eval(&idate2+&s);
			%end;

			*% end of loop;
			%* Save outout set to desired location;
			data &out_ds;
				set _all_ds;
			run;

			proc sort data=&out_ds;
				by &id date2;
			run;

		%end;

	%* end for date check pass section;
%mend;

%rollingreg;
Reeza
Super User

Where are &sdate1 and &sdate2 defined?

 

There looks to be a bunch of logical errors here. Those are just the ones I first saw.

Yamani
Obsidian | Level 7

Thanks for your help. Yes, you are correct. The macro variable year_date has not been set to a value before you used it.

 

The year_date macro variable is used in the code ONLY IF I am using annual data. However, I am using monthly data not annual data, so how I can adjust the code for monthly data?

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 597 views
  • 0 likes
  • 3 in conversation