DATA Step, Macro, Functions and more

Why Are the Macro Variables Not Resolved?

Accepted Solution Solved
Reply
Regular Contributor
Posts: 220
Accepted Solution

Why Are the Macro Variables Not Resolved?

I have attached a SAS program file here.  I just want to store some values as macro variables (not a difficult thing), but I keep getting the warning that the symbolic references are not resolved.  Can anyone explain why?

When I don't use a macro or the %do loop and just specify:

     %let i=1;

     ...run PROC SQL...

     %let i=2;

     ...run PROC SQL...

     %let i=3;

     ...run PROC SQL...

and then run the code, everything works fine, but I need to do loop since the number of groups changes.

Attachment

Accepted Solutions
Solution
‎02-10-2012 09:47 AM
Regular Contributor
Posts: 220

Re: Why Are the Macro Variables Not Resolved?

I was able to get it to work.  I replaced lines 169-202 with the following code:

%do i=1 to &ngroups;

     proc sql noprint;

          select left into :risk&i separated by '|' from estimate where stratum=&i;

     quit;

%end;

%do i=0 %to &nticks;

     %let tickstat&i = %str(tick=) %eval(&i+1) j=c "&&tick&i" j=c;

     %if &i=0 %then %do;

          %let tickstat&i=&&tickstat&i j=c "&&header&j" " %scan(&&risk1,%eval(&i+1),"|&quotSmiley Wink";

          %do j=2 %to &ngroups;

               %let tickstat&i=&&tickstat&i j=c "&&header&j" " %scan(&&risk&j,%eval(&i+1),"|&quotSmiley Wink";

          %end;

     %end;

     %else %do;

          %let %let tickstat&i=&&tickstat&i ' ' j=c "%scan(&risk1,%eval(&i+1),"|&quotSmiley Wink";

          %do j=2 %to &ngroups;

               %let tickstat&i=&&tickstat&i j=c "%scan(&&risk&j,%eval(&i+1),"|&quotSmiley Wink";

          %end;

     %end;

%end;

View solution in original post


All Replies
PROC Star
Posts: 7,363

Why Are the Macro Variables Not Resolved?

I would think you are getting that result because all of the macro variables are local.  Does the following produce what you were expecting?  The only change I made was to move your %put statements into your macro:

data estimate;

          input stratum left @@;

          datalines;

1          3                    1          1                    1          1

1          0                    1          0                    1          0

1          0                    1          0                    1          0

1          0                    1          0                    2          22

2          19                    2          6                    2          1

2          1                    2          1                    2          0

2          0                    2          0                    2          0

2          0                    3          14                    3          13

3          8                    3          3                    3          1

3          1                    3          1                    3          1

3          1                    3          1                    3          1

;

run;

%macro test;

%let ngroups=3;

%let nticks=11;

%let maxtick=%eval(&nticks-1);

%do i=1 %to &ngroups;

          %let i=%sysfunc(compress(&i));

          proc sql noprint;

                    select left into :risk&i.00-:risk&i.&maxtick. from estimate where stratum=&i.;

          quit;

%end;

%put &risk100;

%put &risk101;

%put &risk102;

%put &risk103;

%put &risk104;

%put &risk105;

%put &risk106;

%put &risk107;

%put &risk108;

%put &risk109;

%put &risk110;

%put &risk200;

%put &risk201;

%put &risk202;

%put &risk203;

%put &risk204;

%put &risk205;

%put &risk206;

%put &risk207;

%put &risk208;

%put &risk209;

%put &risk210;

%put &risk300;

%put &risk301;

%put &risk302;

%put &risk303;

%put &risk304;

%put &risk305;

%put &risk306;

%put &risk307;

%put &risk308;

%put &risk309;

%put &risk310;

%mend test;

%test

Regular Contributor
Posts: 220

Why Are the Macro Variables Not Resolved?

I thought if I would have resolved this issue that my whole program would have worked.  Your method did fix my problem that I presented, but inside the larger macro that I am actually using, I try to call each &riskXXX variable, but it still says that they are not found resolved even though I am inside the macro calling local variables.

PROC Star
Posts: 7,363

Why Are the Macro Variables Not Resolved?

Can you post an example?

Super User
Super User
Posts: 6,499

Why Are the Macro Variables Not Resolved?

What are you actually trying to do?  In general I rarely find it useful to generate so many macro variables.

You might consider just using a few variables with the multiple values stores as delimited lists in these variables.

Regular Contributor
Posts: 220

Why Are the Macro Variables Not Resolved?

I am trying to put the number of patients at risk at the bottom of a Kaplan-Meier survival plot.  I am trying to adapt the %survivalplot macro from the 2011 MWSUG conference:

http://www.mwsug.org/prohttp://www.mwsug.org/proceedings/2011/coders/MWSUG-2011-CC08.pdf

I have thought that there might be a simplier way (like putting all the at-risk values in one variable separated by a "|" and then using the scan() function to loop through the variable).  I may just play around with those ideas and see if I can get something more efficient to work.

Thanks Tom and Art!

Regular Contributor
Posts: 220

Why Are the Macro Variables Not Resolved?

By the way, if you are reading the link above, I am having these issues under the "Axis2 Statement" on page 10.

PROC Star
Posts: 7,363

Why Are the Macro Variables Not Resolved?

I still think the Forum would do better seeing the code you are actually running and the specific errors you are getting and at which specific lines.

Regular Contributor
Posts: 220

Re: Why Are the Macro Variables Not Resolved?

Art,

I have attached the full SAS code as well as a csv file to import.  (The import code is included).  Just remember to change the file locations for importing the csv data (line 259) and the output file path in the %survivalplot macro call (variable is figpathname on line 268).

My issues are starting on line 176 in the %do loop where it is trying to call all the &risk variables.

I also have 2 SAS files attached here.  I could not remove the first one.  You need to use the one where the PROC IMPORT statement starts on line 259 (not line 251).

Thanks!

PROC Star
Posts: 7,363

Re: Why Are the Macro Variables Not Resolved?

I don't see any attachments

Regular Contributor
Posts: 220

Re: Why Are the Macro Variables Not Resolved?

See if that works.  If not, send me a message to dbateman@endocyte.com.  I will e-mail you the code and data.

Attachment
Attachment
PROC Star
Posts: 7,363

Re: Why Are the Macro Variables Not Resolved?

Yes, that worked, but I'm not familiar enough with the procs to follow what is happening at each step.

One obvious error, though, is in your macro variable assignments in your proc sql code.  You are trying to create a range between, say, 200 and 29.  Obviously, I don't think that it what you are really trying to do.

Solution
‎02-10-2012 09:47 AM
Regular Contributor
Posts: 220

Re: Why Are the Macro Variables Not Resolved?

I was able to get it to work.  I replaced lines 169-202 with the following code:

%do i=1 to &ngroups;

     proc sql noprint;

          select left into :risk&i separated by '|' from estimate where stratum=&i;

     quit;

%end;

%do i=0 %to &nticks;

     %let tickstat&i = %str(tick=) %eval(&i+1) j=c "&&tick&i" j=c;

     %if &i=0 %then %do;

          %let tickstat&i=&&tickstat&i j=c "&&header&j" " %scan(&&risk1,%eval(&i+1),"|&quotSmiley Wink";

          %do j=2 %to &ngroups;

               %let tickstat&i=&&tickstat&i j=c "&&header&j" " %scan(&&risk&j,%eval(&i+1),"|&quotSmiley Wink";

          %end;

     %end;

     %else %do;

          %let %let tickstat&i=&&tickstat&i ' ' j=c "%scan(&risk1,%eval(&i+1),"|&quotSmiley Wink";

          %do j=2 %to &ngroups;

               %let tickstat&i=&&tickstat&i j=c "%scan(&&risk&j,%eval(&i+1),"|&quotSmiley Wink";

          %end;

     %end;

%end;

Super User
Posts: 5,081

Re: Why Are the Macro Variables Not Resolved?

One approach would be to make all your &RISK variables global.  If that sounds acceptable, here is one way to do it.  Here's what you started with:

%do i=1 %to &ngroups;

%let i=%sysfunc(compress(&i));

proc sql noprint;

  select left into :risk&i.00-:risk&i.&maxtick. from estimate where stratum=&i.;

quit;

%end;

Here's a replacement.  (Other changes, such as moving the PROC statement and removing a %LET statement are made on purpose not by accident):

%local i j;

proc sql noprint;

%do i=1 %to &ngroups;

      %do j=0 %go &maxtick;

              %global risk&i%sysfunc(putn(&j,z2));

      %end;

      select left into : risk&i.00-:risk&i.%sysfunc(putn(&maxtick,z2)) from estimate where stratum=&i;

%end;

quit;

Once the &RISK variables are global, I suspect the rest of the code would work.

Good luck.

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 13 replies
  • 282 views
  • 3 likes
  • 4 in conversation