0
votes

Sample Data:

Reportstatestatus age male hospid radm30 uniquekey Timemonths clinical_cond1 clinical_cond2  
ca1                33  0    1232   1      1           13       0              1
ca1                22  1    2321   1      2           10       1              0
ca0               22   1    2222   0      3           10       1              0

I have a macro like this (code designed by someone else):

 DSN = Dataset Name 
PARMS = Parameters from multivariate model 
KEY = Unique ID or key to match observations 
DEPENDENT = Dependent variable specified in model 
INDEPENDENT = Independent variables separated with spaces 
CLASS = Class variable of interest to calculate marginal effects 
NAME_1 = User provided name for the first data element of class variable 
(Name limited to 30 characters) 
NAME_2 = User provided name for the second data element of class variable 
(Name limited to 30 characters) 
*************************************************************** 
EXAMPLE OF MACRO CALL 
***************************************************************/ 
%MARGINAL(cabg, /* Name of original dataset */ 
parms_OpDeath, /* Parameter estimates from model */ 
medRecN, /* Key */ 
yom, /* Dependent variable */ 
age_n, /* Independent variables listed */ 
GENDER, /* Class variable for marginal effects */ 
Male, /* User-supplied name of first data element*/ 
Female); /* User-supplied name of second data element*/ 
/****************************************************************/ 


%MACRO MARGINAL (DSN,PARMS,KEY,DEPENDENT,INDEPENDENT,CLASS,NAME_1,NAME_2);  
data OUT_1;  
length &CLASS $30
;  
set &DSN (rename=(&CLASS = OLD_CLASS )) ;  
&CLASS = "&NAME_1";  
RUN;  
**** Apply model to entire data; 
PROC LOGISTIC inmodel= &PARMS Descending;  
score data=OUT_1  
OUT= PRED_1 (KEEP = &KEY &DEPENDENT &CLASS &INDEPENDENT OLD_CLASS P_1);  
title "Applying the Risk Model to Entire Data Assuming Every Observation’s 
Class Variable Value = First Data Element of the Class Variable";  
RUN;  
data OUT_2;  
length &CLASS $
30
;  
set &DSN (rename=(&CLASS = OLD_CLASS )) ;  
&CLASS = "&NAME_2";  
RUN;  
**** Apply model to entire data; 
PROC LOGISTIC inmodel= &PARMS Descending;  
score data=OUT_2  
OUT= PRED_2 (KEEP = &KEY &DEPENDENT &CLASS &INDEPENDENT OLD_CLASS P_1);  
title1 "Applying the Risk Model to Data assuming Every Observation’s Class 
Variable Value = Second Data Element of the Class Variable";  
RUN;  
**** Join the data; 
data OUT_1_N;  
set PRED_1;  
p_&NAME_1 = p_1;  
KEEP &KEY &DEPENDENT &CLASS &INDEPENDENT OLD_CLASS p_&NAME_1 ;  
RUN;  
proc sort data=OUT_1_N; by &KEY; RUN;  
data OUT_2_N;  
set PRED_2;  
p_&NAME_2 = p_1;  
KEEP &KEY &DEPENDENT &CLASS &INDEPENDENT OLD_CLASS p_&NAME_2 ;  
RUN;  
proc sort data=OUT_2_N; by &KEY; run;  
data join;  
merge OUT_1_N OUT_2_N;  
by &KEY;  
RUN;  
title "Compare Observed Response Variable: Class Variable Value 1 vs. Class 
Variable Value 2";  
PROC TTEST data=join;  
class OLD_CLASS;  
var &DEPENDENT;  
RUN;  
title "Compare predicted Response Variable with Recycle Prediction Method";  
PROC MEANS data=join n mean std min max lclm uclm;  
var p_&NAME_1 p_&NAME_2 ;  
RUN;  
PROC TTEST data=join;  
paired p_&NAME_1 * p_&NAME_2;  
RUN;  
%MEND MARGINAL;

When I run the macro like this:

libname inputf "F:\ccorp\mray\processed\Readmission";
data work.readmdata;
set INPUTF.readm_caonly;  
run;

%LET indep = age Male TimeMonths Reportstatestatus Hx_CTSURG 
Cardiogenic_Shock COPD MCANCER DIABETES MALNUTRITION DIS_FLUID OBESITY 
HEMATOLOGICAL DEMENTIA MAJOR_PSYCH PARALYSIS_FUNCTDIS POLYNEUROPATHY 
CHF ARRHYTHMIAS CEREB_HEMORR CEREB_DISEASE VASDIS_WCOMP FIBROSIS_LUNG 
PNEUMONIA OTHER_LUNG_DIS DIALYSIS RENALFAILURE DECUBITUS_ULCER ;

(The variables after Reportstatestatus are clinical conditions)

%MARGINAL (%nrbquote(readmdata, /* Name of original dataset */ 
estimates_slopeCA, /* Parameter estimates from model */ 
UniqueKey, /* Key */ 
RADM30, /* Dependent variable */ 
indep, /* Independent variables listed */ 
Reportstatestatus, /* Class variable for marginal effects */ 
CA1, /* User-supplied name of first data element*/ 
CA0)); /* User-supplied name of second data element*/ 

it gives me the error:

ERROR: More positional parameters found than defined.

I have researched online and tried, %STR or %NRSTR, %BQUOTE or %SUPERQ (this didn't run. It gave more errors). I still get the error.

Please help.

4
Has this ever worked before? If yes, then can you supply an example call to %marginal that has worked. Also try using macro options like options symbolgen; and perhaps show more of the log around the error message. We need to be sure the error message is related to %marginal.Amir
Why did you include %NRBQUOTE()? There is nothing that needs quoting. Perhaps you have not ended some previous attempt at macro quoting. Can you start with a fresh SAS session and try again?Tom

4 Answers

0
votes

To test this, a sample data would go a long way but I do believe that the macro quoting function should be used on individual macro parameters and not all the parameters together. Without being able to test I would suggest trying something like this:

%MARGINAL (readmdata, estimates_slopeCA, UniqueKey, RADM30, %bquote(&indep), Reportstatestatus,
CA1, CA0);

0
votes

If there is a problem in the macro call itself, you shouldn't need the data (or even all the macro code). That said, I couldn't replicate your problem.

To debug, I would make a simple macro like:

%MACRO MARGINAL (DSN,PARMS,KEY,DEPENDENT,INDEPENDENT,CLASS,NAME_1,NAME_2);  
  %put _user_ ; 
%MEND MARGINAL;

I successfully called that macro with your code:

%MARGINAL (%nrbquote(readmdata, /* Name of original dataset */ 
estimates_slopeCA, /* Parameter estimates from model */ 
UniqueKey, /* Key */ 
RADM30, /* Dependent variable */ 
indep, /* Independent variables listed */ 
Reportstatestatus, /* Class variable for marginal effects */ 
CA1, /* User-supplied name of first data element*/ 
CA0)); /* User-supplied name of second data element*/ 

By "successfully" I mean it executed the macro, and did not produce the error your report. Because of the use of %NRBQUOTE(), only the DSN parameter is given a value. That is probably not the intended behavior, but it does not create an error. Even if I remove %NRBQUOTE, I don't get an error.

I suggest you edit your question to make a reproducible example.

0
votes

I would put the function in the code and not in the macro input parameter. then force quote it in your use... If you give me your whole macro defenition I can help!

0
votes

Only the last two parameters might need to have macro quoting applied to them in order to make the call. Those two parameters require strings to match possible values of the specified class variable. And even then only if the value includes commas, leading spaces, unbalanced quotes or unbalanced parentheses would you need to add macro quoting.

The other parameters all require dataset or variable names or other valid SAS syntax and so there should be no need to add macro quoting.

%MARGINAL
(DSN=cabg /* Name of original dataset */ 
,PARMS=parms_OpDeath /* Parameter estimates from model */ 
,KEY=medRecN /* Key */ 
,DEPENDENT=yom /* Dependent variable */ 
,INDEPENDENT=age_n /* Independent variables listed */ 
,CLASS=GENDER /* Class variable for marginal effects */ 
,NAME_1=%bquote(1, Male) /* User-supplied name of first data element*/ 
,NAME_2=%bquote(2, Female) /* User-supplied name of second data element*/ 
);