BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
SeanZ
Obsidian | Level 7

Hi. Please help me with this question. I am not sure if this is a problem in macro. I coded a macro in my SAS program. It ran without problems. I did a regression with independent variable x1 and it worked well, I changed the independent variable to x2 in the macro part. (I changed x1 to x2). This is just a simple change, but I got unexpected results. It still shows results for x1. I close the SAS program thoroughly and re open the program, then everything works fine. I don't know what is the problem, and hate to close and open the program every time I change something in the macro. How can I do with this issue? Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

Hi,

Here are some thoughts/questions, I think the last one may be the issue.

1.  If you start a new SAS session and paste in the code you posted, do you replicate the problem? (It works when you run the first time with &x1=mkt but fails when you change it to &x1=smb?

2.  Assuming that does replicate the problem, if you start a new session, and paste in the cdoe, and set &x1=smb for the first frun in that session, does it work?  What if you use &x1=mkt for the second run?

3. When you check the log, are you looking for the FIRST error/warning/ bad note that you see?  if SMB does not exist in the source data, then the first regression will fail.

4  Sprikle your code with: %put x1=>>&x1.<<;  to see how macro vars resolve at each point (and/or turn on OPTIONS SYMBOLGEN).

5. Remember that if you do your testing in an interactive session, all your work datasets will still be around at the end.

Actually, just hit me that #5 may be the key, especially because you are using PROC APPEND with FORCE option.

The first time you run your code with &x1=mkt,  the dataset BETAS1 will have the variable MKT in it (and other variables).  When you then run it a second time with &x1=smb, BETAS1 will already exist from the earlier run, with MKT in it but not SMB.  When you run PROC APPEND with FORCE, I think the records will be appended, but the SMB variable will not be added to the dataaset, because it does not exist in the base dataset.  

If you add proc datasets library=work memtype=data; delete betas1; quit;  to the bottom of your code, it will delete work.betas1 after you run with &x=mkt, so that when you then run wit with &x1=smb the proc append step will create a new dataset, which has smb in it.

HTH,

--Q.

BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

View solution in original post

13 REPLIES 13
UrvishShah
Fluorite | Level 6

Can you please post the sample SAS Code to let the other people know about why did you get the unexpected output...???

I don't think it is BLACK HOLE ERROR in SAS if it is then SAS Stops to respond...It will be better if you post sample code...

-Urvish

SeanZ
Obsidian | Level 7

THank you for your reply. I don't have access to my code today. I can post tomorrow. But my question was described further in the reply to EJ. From there you may seeh what happened to me.

esjackso
Quartz | Level 8

Did you resubmit the macro code to update the compiled macro code available to SAS? That is what is sounds like to me. If you change code in the macro you cant just run the macro call again you must submit the macro definition so SAS can update to the changes made.

EJ

SeanZ
Obsidian | Level 7

Please forgive my ignorance, but what do you mean by resubmit the macro? I clicked on the running figure icon to run my program, and got correct results. Lasted, I changed some numbers in the macro part of my code, and clicked that icon again only to find a wrong result. I saved code revised code, closed the SAS window environment, and reoptied it. Now when I click on the running figure to execute the code, I can get the correct result. Do I have to close the SAS window every time I changed my code? Thanks.

Quentin
Super User

Hi Sean,

No, you do not have to close SAS every time you change your code.  But, there are mistakes you could make in the code that could give you that impression.  Posting your code will help folks help you.  And as with any debugging exercise, try to narrow it down to the simplest example that shows your problem.  That will also make it easier for forlks to help you.  Often I find that when I go through the exercise of excluding extraneous code to make a nice clear example to post to the group, the solution becomes apparent.

-Q.

BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
esjackso
Quartz | Level 8

I agree without seeing the code we can only offer general help.

EJ

Tom
Super User Tom
Super User

The code between the %MACRO and %MEND statements DEFINE the macro.  Then at some other place in your code you execute the macro by calling it with something like: %macroname.

When you run the code that has the %MACRO statement the macro is compiled.  Then when you run the code with the %macroname call the macro executes.  So if you make changes in the code between the %macro and %mend statements without re-running that part of the program the definition of the macro will not change.

The other thing to check is that you have properly closed all of your comments, quoted string and data steps and procedutes. It is possible that the first few lines of the second attempt to run the program are not being run because of this type of confusion.

esjackso
Quartz | Level 8

Great explanation and tips !

The evil orphaned quotation mark has drove me to bang my head against the wall with some of my programs!

EJ

SeanZ
Obsidian | Level 7

Thank you all for the helpful comments. I post part of the code I wrote. In the data set imported (temp), there are variables mkt, smb, ret, and others. I use %let x1=mkt for the first run, I got correct results. Later, I change the code to %let x1=smb for a new run. I cannot get  the correct result. Error message shows that there is no variable smb found. When I checked the interim step, I found that although I changed the code to "smb", the data still showed old variable "mkt" instead of new one I expected. Please help me check what's wrong with it. Thanks.

-----------------------------------------------------------------------------------

options nosource nodate nocenter nonumber ps=max;

title 'Fama-MacBeth Rolling Regression Results ';

ods html close;

ods preferences;

ods html newfile=proc;

proc import datafile="D:\work\data.dta" out=temp dbms = dta replace; * out= name of file of output, in work folder;

run;

*Compute time series regressions each month and save the coefficients;

proc sort data = temp;

by productreference n;

run;

* Define independent and dependent variables;

%let x1=mkt;

%let y=ret;

%macro tsreg; * time series regression;

%do m = 37 %to 216; * from month 37 to 216;

    data roll; set temp;

  if &m - 36 <= n < &m; * Past 36 months data;

  mon = &m;

  proc reg data=roll noprint outest=results EDF;

  model &y=&x1;

  by productreference mon;

  run;

  proc append base = betas1 data = results force; * append data "results" and save to betas1;

%end;

%mend tsreg;

%tsreg

* Include only those have 36 observations;

proc sql;

create table betas as

  select productreference, &x1, mon, (_EDF_ + _P_) as obs

  from betas1

  having (_EDF_ + _P_) = 36;

quit;

/* Merge betas with next month return*/;

proc sql;

  create table fmb as

  select *

  from betas(drop=obs) a, temp(keep=productreference &y n) b

  where a.productreference = b.productreference and

   a.mon = b.n;

quit;

/* Cross-sectional regression to get monthly premium and intercept*/

proc sort data = fmb;

by n;

run;

proc reg data = fmb noprint outest = final;

model &y = &x1;

by n;

run;

proc means mean n std t prt data = final; * Time series average of intercept and mkt coefficient;

var intercept &x1;

run;

quit;

Quentin
Super User

Hi,

Here are some thoughts/questions, I think the last one may be the issue.

1.  If you start a new SAS session and paste in the code you posted, do you replicate the problem? (It works when you run the first time with &x1=mkt but fails when you change it to &x1=smb?

2.  Assuming that does replicate the problem, if you start a new session, and paste in the cdoe, and set &x1=smb for the first frun in that session, does it work?  What if you use &x1=mkt for the second run?

3. When you check the log, are you looking for the FIRST error/warning/ bad note that you see?  if SMB does not exist in the source data, then the first regression will fail.

4  Sprikle your code with: %put x1=>>&x1.<<;  to see how macro vars resolve at each point (and/or turn on OPTIONS SYMBOLGEN).

5. Remember that if you do your testing in an interactive session, all your work datasets will still be around at the end.

Actually, just hit me that #5 may be the key, especially because you are using PROC APPEND with FORCE option.

The first time you run your code with &x1=mkt,  the dataset BETAS1 will have the variable MKT in it (and other variables).  When you then run it a second time with &x1=smb, BETAS1 will already exist from the earlier run, with MKT in it but not SMB.  When you run PROC APPEND with FORCE, I think the records will be appended, but the SMB variable will not be added to the dataaset, because it does not exist in the base dataset.  

If you add proc datasets library=work memtype=data; delete betas1; quit;  to the bottom of your code, it will delete work.betas1 after you run with &x=mkt, so that when you then run wit with &x1=smb the proc append step will create a new dataset, which has smb in it.

HTH,

--Q.

BASUG is hosting free webinars Next up: Jane Eslinger presenting PROC REPORT and the ODS EXCEL destination on Mar 27 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
SeanZ
Obsidian | Level 7

Thank you a lot for your time. It's a perfect solution. I verified it by manually remove beta1 data after the first run, change the variables, and retest it with correct answer. It is the beta1 file that caused the problem. Now I have another question. I would like to do a loop to run them together. Specifically, I have about 15 regressors. I want to do univariate regression (ret vs. each of 15 regressors) 15 times. So I set

%let x1=mkt;

%let x2=smb;

%let x3=hml;

...

%let y=ret;

mkt smb hml and so on are just factors (regressors). Is it easy to write a do loop outside my code to do it? I can write it easily in Matlab or STATA, but for SAS I am just a newbie. I appreciate a lot.

Tom
Super User Tom
Super User

You could keep your program the same and change the PROC APPEND to :

data betas1 ;

   set betas1 results;

run;


To make sure there is a BETAS1 file before your macro call run you could use this simple data step:


data betas1; stop; run;


to create an empty dataset (no variables and no observations).



SeanZ
Obsidian | Level 7

thanks a lot! That works great!

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 13 replies
  • 1269 views
  • 8 likes
  • 5 in conversation