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

Hi!

 

I'm using the %margins macro (version 1.07) from https://support.sas.com/kb/63/038.html#use but can't seem to get the within parameter to work correctly. I understand it can be specified like a where statement i.e. within=exposed=1 but the error I keep getting is below. I don't think it's an error in my specification. Anyone knows how I can address this?

 

ERROR: Variable _within is not on file WORK._POP.
WARNING: The data set WORK._ETA may be incomplete. When this step was stopped there were 0 observations and 0 variables.
WARNING: Output 'Cov' was not created. Make sure that the output object name, label, or path is spelled correctly. Also, verify
that the appropriate procedure options are used to produce the requested output object. For example, verify that the
NOPRINT option is not used.
ERROR: File WORK._MU.DATA does not exist.
ERROR: Variable _within is not on file WORK._POP.
ERROR: File WORK._MU.DATA does not exist.
WARNING: The data set WORK._X may be incomplete. When this step was stopped there were 0 observations and 2 variables.
ERROR: Replicates data set, _X, is empty. No data to analyze.
NOTE: The MARGINS macro used 4.28 seconds.

1 ACCEPTED SOLUTION

Accepted Solutions
StatDave
SAS Super FREQ

Thanks for showing your macro call. I first have to say that I don't think it makes much sense to specify one level of the margins= variable as the within= condition. If you just want the predictive margins for one level of a CLASS variable in the model, then specify the variable in margins= and don't use within=. Yes, it will give the predictive margins for all levels of that variable, but you can simply ignore the ones you don't want. So, I suggest you simple remove within= from your macro call to fix your problem.

 

That said, it does appear that there is a problem in the macro. If macro parameters related to a GEE model (or freq=, weight=, or offset=) are specified, then within= is effectively ignored causing the error. A possible fix to the problem, which has obviously not been fully tested, is the following. Find this section in the macro code and change it as shown. But again, I think this fix is only needed when NOT using a condition like what you showed. Note the change of "&" to "_" in the MERGE statement and then the added macro statement in the KEEP= option. 

data _data; 
  merge _data _glmsout;
  if _p ne .;
  drop _p;
  run;
%let modelDum = %upcase(&_glsmod);
%let modelDumInt = &modelDum;
%if &int %then %let modelDumInt = INTERCEPT &modelDum;
%let nmodeffs=%sysfunc(countw(&modelDumInt, ' '));
%let chk=&freq &weight &offset &geesubvars &geewvars;
%if &chk ne %then %do;
  data _expdata;
    merge _expdata _data(keep=&freq &weight &offset &geesubvars &geewvars
                         %if %quote(&within) ne %then _within;
                         );
    run;
%end;

View solution in original post

10 REPLIES 10
ballardw
Super User

The first error you show is a likely culprit for causing other errors latter. You have used "_within" where whatever was entered is expected to be a VARIABLE and your data set does not contain that variable.

 

I might guess that you actually placed the keyword _within in the macro parameter where the macro expects something like  within= exposed=1 but you wrote: within= _within=exposed=1 (the full statement as opposed to just the value of the _within statement)

 

You can get more details of what is happening when running macro code by placing the system option statement: options mprint; before execution. Example;

 

options mprint;

%mymacrocall(parm=something);

options nomprint;  <this turns the extra output off>

 

The log will show the generated code along with the error message(s) so you can see more of the code that created the specific error.

 

Note: Generally posting error messages only is suboptimal. The code submitted, as a minimum, such as the macro call. Better is the full LOG containing the submitted code that generates the error as well as all of the warnings, notes or errors. Copy the first procedure, data step or macro call through the end from the Log and paste into a code box opened on the forum with the </> to preserve the text generated by SAS. Errors or warnings often have diagnostic information that the message windows on the forum will reformat making the diagnostic information less useful or illegible.

user20
Fluorite | Level 6
25         GOPTIONS ACCESSIBLE;
26         %Margins(
27         data=nsw_splbasis,
28         margins=exposed,
29         response=pih,
30         within=exposed=1,
31         class=exposed year_cat age_cat parity cob ever_smoke mother_id,
32         model=exposed _X: year_cat age_cat parity cob ever_smoke,
33         dist=poisson,
34         link=log,
35         geesubject=mother_id,
36         geecorr=exch,
37         options=diff cl);
ERROR: Variable _within is not on file WORK._POP.
WARNING: The data set WORK._ETA may be incomplete.  When this step was stopped there were 0 observations and 0 variables.
WARNING: Output 'Cov' was not created.  Make sure that the output object name, label, or path is spelled correctly.  Also, verify 
         that the appropriate procedure options are used to produce the requested output object.  For example, verify that the 
         NOPRINT option is not used.
ERROR: File WORK._MU.DATA does not exist.
ERROR: Variable _within is not on file WORK._POP.
ERROR: File WORK._MU.DATA does not exist.
WARNING: The data set WORK._X may be incomplete.  When this step was stopped there were 0 observations and 2 variables.
ERROR: Replicates data set, _X, is empty. No data to analyze.
NOTE: The MARGINS macro used 2.86 seconds.
38         
39         GOPTIONS NOACCESSIBLE;
40         %LET _CLIENTTASKLABEL=;
41         %LET _CLIENTPROCESSFLOWNAME=;
42         %LET _CLIENTPROJECTPATH=;
43         %LET _CLIENTPROJECTPATHHOST=;
44         %LET _CLIENTPROJECTNAME=;
45         %LET _SASPROGRAMFILE=;
2                                                          The SAS System                                09:27 Friday, July 16, 2021

46         %LET _SASPROGRAMFILEHOST=;
47         
48         ;*';*";*/;quit;run;
49         ODS _ALL_ CLOSE;
50         
51         
52         QUIT; RUN;

Apologies, please see above.

user20
Fluorite | Level 6
It works fine if I omit the within statement, but that's not the results I would like.
Tom
Super User Tom
Super User

That macro seems to override your options settings and hiding all of the notes in the log that would let you see where the issue is.

%if %index(%upcase(&version),DEBUG)=0 %then options nonotes;;

You can use its DEBUG or DEBUG2 option to have it turn on the options so you can see what code it is generating.

%margins(DEBUG
,data=nsw_splbasis
,margins=exposed
,response=pih
,within=exposed=1
,class=exposed year_cat age_cat parity cob ever_smoke mother_id
,model=exposed _X: year_cat age_cat parity cob ever_smoke
,dist=poisson
,link=log
,geesubject=mother_id
,geecorr=exch
,options=diff cl
);

PS: Place continuation characters (commas in this case) at the BEGINNING or the line instead of the END of the line so that humans can more easily see them when scanning the code.

 

Also make sure you don't have the WORK._DATA dataset locked or have view named WORK._DATA that will interfere with the step that is using the WITHIN parameter to create a _WITHIN variable in the data.  Here is the relevant lines from the macro's source code (with formatting cleaned up so that you more easily tell the difference between the macro code and the SAS the macro is generating).

data _data;
  set &data nobs=_in;
%if &freq ne %then
  &freq=int(&freq);
;
  call symput('nin',cats(_in));
%if %quote(&within) ne %then %do;
  _within = (%str(&within));
%end;
run;

 

user20
Fluorite | Level 6

Thanks, how do I make sure any WORK._DATA  dataset that gets created is not locked and/or not a view? Using the DEBUG gives me the below which is no more enlightening to me. I feel there is something not right with the macro itself; and not something I have done?

 

MLOGIC(MARGINS):  %DO loop index variable I is now 3; loop will not iterate again.
MPRINT(MARGINS):   proc plm restore=_Fit;
MPRINT(MARGINS):   show covariance;
MPRINT(MARGINS):   ods output Cov=_Cov;
SYMBOLGEN:  Macro variable WITHIN resolves to exposed=1
MLOGIC(MARGINS):  %IF condition %quote(&within) ne is TRUE
ERROR: Variable _within is not on file WORK._POP.
46                                                         The SAS System                                09:27 Friday, July 16, 2021

MPRINT(MARGINS):   score data=_Pop (where=(_within=1)) out=_Eta(rename=(Predicted=_eta));
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK._ETA may be incomplete.  When this step was stopped there were 0 observations and 0 variables.
WARNING: Data set WORK._ETA was not replaced because this step was stopped.
NOTE: PROCEDURE PLM used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds
      
WARNING: Output 'Cov' was not created.  Make sure that the output object name, label, or path is spelled correctly.  Also, verify 
         that the appropriate procedure options are used to produce the requested output object.  For example, verify that the 
         NOPRINT option is not used.
SYMBOLGEN:  Macro variable WITHIN resolves to exposed=1
MLOGIC(MARGINS):  %IF condition %quote(&within) ne is TRUE
MPRINT(MARGINS):   score data=_Pop (where=(_within=1)) out=_Mu (rename=(Predicted=_mu )) / ilink;
MPRINT(MARGINS):   run;

 

 

Tom
Super User Tom
Super User

So now that you can see where the error is occurring and the actual steps of SAS code that the macro is generating you need to look backwards into your SAS log and see WHY that variable does not exist on that dataset _POP. 

 

Look back to see how was _POP created? Were there any notes in the log for the step that created _POP?

 

 

StatDave
SAS Super FREQ

Thanks for showing your macro call. I first have to say that I don't think it makes much sense to specify one level of the margins= variable as the within= condition. If you just want the predictive margins for one level of a CLASS variable in the model, then specify the variable in margins= and don't use within=. Yes, it will give the predictive margins for all levels of that variable, but you can simply ignore the ones you don't want. So, I suggest you simple remove within= from your macro call to fix your problem.

 

That said, it does appear that there is a problem in the macro. If macro parameters related to a GEE model (or freq=, weight=, or offset=) are specified, then within= is effectively ignored causing the error. A possible fix to the problem, which has obviously not been fully tested, is the following. Find this section in the macro code and change it as shown. But again, I think this fix is only needed when NOT using a condition like what you showed. Note the change of "&" to "_" in the MERGE statement and then the added macro statement in the KEEP= option. 

data _data; 
  merge _data _glmsout;
  if _p ne .;
  drop _p;
  run;
%let modelDum = %upcase(&_glsmod);
%let modelDumInt = &modelDum;
%if &int %then %let modelDumInt = INTERCEPT &modelDum;
%let nmodeffs=%sysfunc(countw(&modelDumInt, ' '));
%let chk=&freq &weight &offset &geesubvars &geewvars;
%if &chk ne %then %do;
  data _expdata;
    merge _expdata _data(keep=&freq &weight &offset &geesubvars &geewvars
                         %if %quote(&within) ne %then _within;
                         );
    run;
%end;
user20
Fluorite | Level 6

Hello there,

 

Firstly, thank you so much - your suggested fix worked and allowed the margins call to run without issues. Apologies also for the delayed response.

 

Secondly, I am trying to find the marginal effects in the 'exposed' group (or the 'treatment' group), rather than averaged across the entire population. In other words, the 'effect of the treatment in the treated'. Given this, would you agree that I need to specify the variable in both margins= and within= ?

 

Thanks so much again.

StatDave
SAS Super FREQ

I see. Well, if that is what you want to estimate, then I guess your code is correct.

 

BTW, the Margins macro has been updated (to version 1.08) to include the fix mentioned above. When you run the macro, a message should appear in the SAS log to notify you that a new version is available.

StatDave
SAS Super FREQ

As always, in order to help you need to show the submitted code that resulted in errors - in this case, please show the Margins macro call that you submitted.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
What is ANOVA?

ANOVA, or Analysis Of Variance, is used to compare the averages or means of two or more populations to better understand how they differ. Watch this tutorial for more.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 10 replies
  • 2078 views
  • 6 likes
  • 4 in conversation