BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
djbateman
Lapis Lazuli | Level 10

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.

1 ACCEPTED SOLUTION

Accepted Solutions
djbateman
Lapis Lazuli | Level 10

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),"|")";

          %do j=2 %to &ngroups;

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

          %end;

     %end;

     %else %do;

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

          %do j=2 %to &ngroups;

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

          %end;

     %end;

%end;

View solution in original post

13 REPLIES 13
art297
Opal | Level 21

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

djbateman
Lapis Lazuli | Level 10

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.

art297
Opal | Level 21

Can you post an example?

Tom
Super User Tom
Super User

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.

djbateman
Lapis Lazuli | Level 10

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!

djbateman
Lapis Lazuli | Level 10

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

art297
Opal | Level 21

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.

djbateman
Lapis Lazuli | Level 10

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!

art297
Opal | Level 21

I don't see any attachments

djbateman
Lapis Lazuli | Level 10

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

art297
Opal | Level 21

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.

djbateman
Lapis Lazuli | Level 10

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),"|")";

          %do j=2 %to &ngroups;

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

          %end;

     %end;

     %else %do;

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

          %do j=2 %to &ngroups;

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

          %end;

     %end;

%end;

Astounding
PROC Star

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.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

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