DATA Step, Macro, Functions and more

Using a macro variable to scan another macro variable

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 5
Accepted Solution

Using a macro variable to scan another macro variable

I am stuck trying to read a macro variable containing a list of values by using the %scan function to find which list is going to be scanned for a value. Here is an example:

1. I have the following list;

%let list_cci=MI CHF CVD PVD DEM CPD CTDRD PUD MLD diab_wc diab_c P_H RD CAN MSLD MC HIV;

2. There are lists created named after each values of the list_cci list;

%let MI=410 412;

%let CHF=39891 40201 40211 4291 40401 40403 40411 40413 40491 40493 4254 4255 4257 4258 4259 428;

...

3. The idea is that I want to scan the list, assign a value to a macro variable, and then use that macro variable to tell sas which list to scan for another value. I need to do this in 2 steps because the variable name (MI, CHF, CVD, etc.) is important. However, when

4. Here is what I have done so far, within 2 %do loops that run from 1 to &i and &j:

%let diagname = &%scan(&list_cci.,&i.);

%put &diagname; /*gives me e.g. &MI */

%let var=%scan(&diagname,&j.); /*--->here I expect it would scan the MI list, because &MI is put in the %scan function*/

%put &var; /* but all I get is the jth value from the &list_cci list... even though %put &diagname; gives me &MI!*/

Any ideas why it would scan the first list when I ask to basically %scan(&MI,&j.)? Any other idea how I could solve this?


Accepted Solutions
Solution
‎07-23-2012 01:47 PM
Super User
Posts: 5,518

Re: Using a macro variable to scan another macro variable

A few issues have arisen here.  Let's go back to the original problem and modify the approach slightly.

Don't try to assign a value that includes an ampersand.  Try to assign MI, instead of &MI as the value of &DIAGNAME.  That should be easy enough.

Then to retrieve the value of &MI, refer to &&&DIAGNAME.  That should take care of everything.

Good luck.

View solution in original post


All Replies
Super User
Posts: 11,343

Re: Using a macro variable to scan another macro variable

I think what you may be looking for is %let var = %scan(&&diagname,&j);  You want the referenced variable to be evaluated so need the extra &

Also, in some cases ending your macro variables end with a period all the time will result in unexpected results when they concatenate to something undesired.

Occasional Contributor
Posts: 5

Re: Using a macro variable to scan another macro variable

the ampersand was already added when defining the diagname variable, %let diagname=&%scan(&list_cci.,&i.);

the problem here is that the &diagname variable, even though it gets assigned the right value (&MI for example), when used in the %scan(&diagname,&j.), it browses the first list, as if I hand entered %scan(list_cci,&j.)...

Just to be sure I tried what you said but it's the same as putting the ampersand when defining the diagname macro variable

Super Contributor
Posts: 282

Re: Using a macro variable to scan another macro variable

Hi,

I just tried your lines of code, setting i and j to 1:

%let list_cci=MI CHF CVD PVD DEM CPD CTDRD PUD MLD diab_wc diab_c P_H RD CAN MSLD MC HIV;

%let MI=410 412;

%let CHF=39891 40201 40211 4291 40401 40403 40411 40413 40491 40493 4254 4255 4257 4258 4259 428;

%let i=1;

%let j=1;

%let diagname = &%scan(&list_cci.,&i.);

%put &diagname; /*gives me e.g. &MI */

%let var=%scan(&diagname,&j.);

%put &var;

and var had a value of 410. Is that what you were expecting?

Regards,

Amir.

Occasional Contributor
Posts: 5

Re: Using a macro variable to scan another macro variable

it is... which is weird! I found out something: if I put spaces before and after the = sign, I get 410. If I don't (and use j and i=1), I get "scan"... I didn't know spaces around equal signs would influence the result?!


Thanks a lot for that!

Contributor
Posts: 52

Re: Using a macro variable to scan another macro variable

That does not sound like a good result. Spaces don't usually make a difference (except I was counting spaces above to figure how how many codes were in the diagnosis lists). I'd suggest being careful about the extraneous ampersands. For example, in the original code, you have: %let diagname = &%scan(&list_cci.,&i.); I think that first ampersand is unnecessary here and wonder if it's causing your problem.

Occasional Contributor
Posts: 5

Re: Using a macro variable to scan another macro variable

You are right, I was wrong, it's not working. The thing that bugs me is I need to put the ampersand besore the scan function in order that the value of &diagname be &MI and not only MI, so that when I do the %scan on &diagname, it doesnt scan "MI" but rather "&MI", hence the list contained in the &MI variable... that's what I've been trying to figure out

Contributor
Posts: 52

Re: Using a macro variable to scan another macro variable

My hunch is that the issue is with the do loops. In the following code, I nest them and provide a dynamic end point to the inner loop. You should do that for the outer loop too, but your code gives list for only the first two:

%let list_cci=MI CHF CVD PVD DEM CPD CTDRD PUD MLD diab_wc diab_c P_H RD CAN MSLD MC HIV;

%let MI=410 412;

%let CHF=39891 40201 40211 4291 40401 40403 40411 40413 40491 40493 4254 4255 4257 4258 4259 428;

%do i = 1 %to 2;

  

   %let diagname = %scan(&list_cci, &i);

   %let number_of_diagnosis_codes = %eval(%sysfunc(count(&diagname, %str( )))+1);

  

   %do j = 1 %to &number_of_diagnosis_codes;

  

      ... do something...

  

   %end;

%end;

Hope this helps,

Tish

Solution
‎07-23-2012 01:47 PM
Super User
Posts: 5,518

Re: Using a macro variable to scan another macro variable

A few issues have arisen here.  Let's go back to the original problem and modify the approach slightly.

Don't try to assign a value that includes an ampersand.  Try to assign MI, instead of &MI as the value of &DIAGNAME.  That should be easy enough.

Then to retrieve the value of &MI, refer to &&&DIAGNAME.  That should take care of everything.

Good luck.

Occasional Contributor
Posts: 5

Re: Using a macro variable to scan another macro variable

Posted in reply to Astounding

That works! thanks a lot. If I may ask, why 3 &'s? Not sure about the logic behind this..

Super User
Posts: 5,518

Re: Using a macro variable to scan another macro variable

SAS resolves these macro strings in pieces, from left to right.  There are two pieces in &&&DIAGNAME:  && and &DIAGNAME.

&& resolves into &

&DIAGNAME resolves (in this case) to MI.

So the combined string resolves to &MI.  Then SAS notices it still needs to re-scan the string because macro resolution isn't yet complete.

Super User
Super User
Posts: 7,083

Re: Using a macro variable to scan another macro variable

SAS will scan the code twice to resolve the macro references.  On the first pass && is resolved to & and &diagname is resolved to its value (say MI).  So now on the next pass you have &MI which will resolve to the list ICD9 codes.

🔒 This topic is solved and locked.

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

Discussion stats
  • 11 replies
  • 393 views
  • 1 like
  • 6 in conversation