0

I am new to SAS and want to make a macro procedure that creates y-axis values for a later PROC GPLOT.

In plain English, there are two posssible minimum values (and maxs) on this graph. The axis range is dependent on which minimum value is the smallest. Otherwise, SAS will not display data outside the axis range. I do NOT want SAS to automatically create the range for me. I want to define the range myself.

So, this is my attempt at a procedure that a) calculates two minimum values, b) compares the two, and c) stores the smaller of the two in a new macro variable. If I can get this one to work, a max procedure would be easy to do.

%MACRO min;
%LET ymin1 = %SYSEVALF(&minresult - (((&minresult + &maxresult)/2) * .05);
%PUT ymin1 = &ymin1;
%LET ymin2 = %SYSEVALF(&min - (&min * .05));
%PUT ymin2 = &ymin2;
%IF &ymin1 > &ymin2
%THEN %LET ymin = ymin2;
%ELSE %LET ymin = ymin1;
%PUT ymin = &ymin;
%MEND min;

I have a feeling I am doing something wrong syntactically. Any help is appreciated.

Joe
  • 62,789
  • 6
  • 49
  • 67
  • A few notes - there is no such thing as a macro procedure; `macro` is the term itself. `PROC FCMP` allows you to create functions and procedures, but they're not in the macro language - rather in something close to the data step language. Also, you should define &min/&minresult/&max/&maxresult as macro parameters; even if they exist as global macro variables, it's better style-wise to define them again. You can still call %min(&min,&max,&minresult,&maxresult) and it will work fine. – Joe Jun 06 '13 at 19:57

1 Answers1

2

The simple solution is to skip the %if stuff and just define ymin from ymin1/2:

%let ymin = %sysfunc(min(&ymin1,&ymin2));

The specific syntax error you have, other than a missing ) in the first ymin declaration, is that %let ymin = ymin2; should be %let ymin=&ymin2;. Otherwise it just contains the text "ymin2", not the contents of the macro variable.

The entire macro:

%MACRO min(minresult,maxresult,min,max);
%LET ymin1 = %SYSEVALF(&minresult - (((&minresult + &maxresult)/2) * .05));
%PUT ymin1 = &ymin1;
%LET ymin2 = %SYSEVALF(&min - (&min * .05));
%PUT ymin2 = &ymin2;
%let ymin = %sysfunc(min(&ymin1,&ymin2));
%PUT ymin = &ymin;
%MEND min;

%min (5,6,3,4);
Joe
  • 62,789
  • 6
  • 49
  • 67
  • In this case, the min( ) called by %sysfunc is the SAS min function, not related to your macro in any way other than name and purpose. You could also execute this in open code if you have ymin1/ymin2 defined and/or construct them in the sysfunc call. You wouldn't have to use SYSEVALF if you did it there. – Joe Jun 06 '13 at 19:58
  • You're right the %sysfunc does make this much easier. However, now I am getting a "ERROR: Open code statement recursion detected." – Wendell Shirley Jun 06 '13 at 20:17
  • Can you rewrite the procedure? – Wendell Shirley Jun 06 '13 at 20:18
  • Most commonly, open code recursion means you missed a semicolon somewhere. – Joe Jun 06 '13 at 20:20