I have a macro that creates a model for me to test heteroskedasticity on whitened residuals and exogenous variables. However, I get the error that the statements is not valid. I have the macro printing out what it is doing and if I take the print out and paste it into a SAS file it runs with no problem. So why is it giving me this error when I run it through the macro?? Here is my log output:
MPRINT(COCHRANE_ORCUTT): proc model data = model_data_estimation; MPRINT(COCHRANE_ORCUTT): parms intercept 0 b1 0 rho1 0; MPRINT(COCHRANE_ORCUTT): y = rho1*lag(y) + (intercept + b1 * x) - rho1*lag(intercept + b1 *x); NOTE: Line generated by the macro variable "WHITENEDVAR". 1 whitened_x -- 180 MPRINT(COCHRANE_ORCUTT): whitened_x = x - rho1 * LAG(x); MPRINT(COCHRANE_ORCUTT): fit y / BREUSCH=(1 whitened_x); MPRINT(COCHRANE_ORCUTT): run; ERROR 180-322: Statement is not valid or it is used out of proper order.
Here is the snippet of the macro code:
%let whitened_vars = ; %let count=1; %let word=%qscan(&iv, &count, %str( )); %do %while(&word ne); %let word=%qscan(&iv, &count, %str( )); %if(&word ne) %then %do; %let count=%eval(&count+1); %let whitened_vars = &whitened_vars whitened_&word; %end; %end; %put &whitened_vars; proc model data = &data; parms ¶meters; &modelspec; %let count=1; %let word=%qscan(&iv, &count, %str( )); %do %while(&word ne); %let word=%qscan(&iv, &count, %str( )); %if(&word ne) %then %do; %let count=%eval(&count+1); %let whitenedvar = whitened_&word; &whitenedvar = &word - rho1 * LAG(&word); %end; %end; fit &y / BREUSCH=(1 &whitened_vars); run; %end;
In the situation that you decscribe (macro is producing correct code in the log but erroring at a valid statement), usually (always?) the problem is the macro language failed to unquote something. Macro quoting symbols are supposed to be automatically unquoted before they get to SAS compiler, and it they aren't, they can cause problems.
Since you are using %QSCAN, you are using macro quoting.
I would replace this part of your macro that returns SAS code:
&whitenedvar = &word - rho1 * LAG(&word);
with:
%unquote(&whitenedvar) = &word - rho1 * LAG(&word);
And see if that fixes it, or at least changes the error you get. It's possible &word will also need to be unquoted, so you could also try:
%unquote(&whitenedvar) = %unquote(&word) - rho1 * LAG(%unquote(&word));
You tried using MPRINT when running a macro, and then copying the generated code from the sas log to a SAS program for retesting, which did not reproduce the error.
I suggest going one step further in the test. Use the MFILE option as well as the MPRINT option. This will write the generated macro code to a file, ready for re-running. Not sas log notes or similar stuff to edit out.
options mprint mfile;
filename mprint 'TEMPOUT';
Running your code after this will write exactly what the sas macro processor produced to TEMPOUT. You can then run that code and get exact line numbers for any error.
I ouput the code to a file as you suggested and here is what the macro ouput:
proc model data = model_data_estimation;
parms intercept 0 b1 0 rho1 0;
y = rho1*lag(y) + (intercept + b1 * x) - rho1*lag(intercept + b1 * x);
whitened_x = x - rho1 * LAG(x);
fit y / BREUSCH=(1 whitened_x);
run;
Which is exactly what I want. I ran this code and it works fine with no errors. So I still don't understand why I am getting an error when it runs through the macro. I am really at a loss here. Any ideas? I have a ton of these models to run so it would take a while to write these out manually.
Well, this isn't a solution to the particular problem you're encountering, but it is something to watch for down the road. Long variable names will cause a problem. When your variable name is X you generate WHITENED_X= which is fine. But if your variable name were 24 characters or longer, there wouldn't be room to prefix it with WHITENED_ and still remain within SAS's 32-character limit for variable names.
In the situation that you decscribe (macro is producing correct code in the log but erroring at a valid statement), usually (always?) the problem is the macro language failed to unquote something. Macro quoting symbols are supposed to be automatically unquoted before they get to SAS compiler, and it they aren't, they can cause problems.
Since you are using %QSCAN, you are using macro quoting.
I would replace this part of your macro that returns SAS code:
&whitenedvar = &word - rho1 * LAG(&word);
with:
%unquote(&whitenedvar) = &word - rho1 * LAG(&word);
And see if that fixes it, or at least changes the error you get. It's possible &word will also need to be unquoted, so you could also try:
%unquote(&whitenedvar) = %unquote(&word) - rho1 * LAG(%unquote(&word));
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.