DATA Step, Macro, Functions and more

Trouble with call symput

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 82
Accepted Solution

Trouble with call symput

I have a dataset that looks like this:

DXCODE     NUMBER

78060          1

7784            2

09989          3

I am trying to create 3 global macro variables called "macrovariable1", "macrovariable2", and "macrovariable3", which have the DXCODE values "78060", "7784", and "09989", respectively.

Here is my macro:

%macro macrovariables;

%do i=1 %to 3;

    data _null_;

    set codes;

    where number = &i;

    call symput('macrovariable' || trim(left(&i)), '"' || trim(left(dxcode)) || '"');

    run;

%end;

%mend macrovariables;

I want this macro to replicate the following code:

data _null_;

set codes;

where number = 1;

call symput('macrovariable1', "78060");

run;

data _null_;

set codes;

where number = 1;

call symput('macrovariable1', "78060");

run;

data _null_;

set codes;

where number = 2;

call symput('macrovariable2', "7784");

run;

data _null_;

set codes;

where number = 3;

call symput('macrovariable3', "09989");

run;

Unfortunately, this code does not generate the global macro variables that I want.  What am I doing wrong?  Thanks.


Accepted Solutions
Solution
‎05-07-2014 03:00 PM
Regular Contributor
Posts: 217

Re: Trouble with call symput

Chuakp,

If you look in my log, my code produced three local macro variables. If you need the macro variables to be global, then simply add a statement to define them as such "%global Macrovariable&i." immediately after the do i=1 to 3 statement.  It worked for me.

View solution in original post


All Replies
Super User
Posts: 5,080

Re: Trouble with call symput

It looks like your problem lies in the first argument to CALL SYMPUT.  Part of that would look like this on the third iteration:

trim(left(3))

You would expect the DATA step to complain that it can't apply the LEFT function to the number 3, it can only apply it to a character string.  Try a simpler version for the first argument that uses double quotes instead of single:

call symput("macrovariable&i", ...

That should take care of the problem.

Frequent Contributor
Posts: 82

Re: Trouble with call symput

Thanks for the suggestion.  I changed the code to:

call symput("macrovariable&i", '"' || trim(left(dxcode)) || '"');

I am still not getting this to work despite the change, unfortunately.

Regular Contributor
Posts: 217

Re: Trouble with call symput


Chuakp,

Try this:

%macro macrovariables;

%do i=1 %to 3;
%let mv = macrovariable;
    data _null_;
    set codes;
    where number = &i.;
    call symput("macrovariable&i.",trim(left(dxcode)));
    run;
%end;

%mend macrovariables;

180  %macro macrovariables;
181
182  %do i=1 %to 3;
183  %let mv = macrovariable;
184      data _null_;
185      set codes;
186      where number = &i.;
187      call symput("macrovariable&i.",trim(left(dxcode)));
188      run;
189  %put "macrovariable&i. = &&&mv.&i.";
190  %end;
191
192  %mend macrovariables;
193
194  %macrovariables;

NOTE: There were 1 observations read from the data set WORK.CODES.
      WHERE number=1;
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


"macrovariable1 = 78060"

NOTE: There were 1 observations read from the data set WORK.CODES.
      WHERE number=2;
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


"macrovariable2 = 7784"

NOTE: There were 1 observations read from the data set WORK.CODES.
      WHERE number=3;
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


"macrovariable3 = 09989"

Frequent Contributor
Posts: 82

Re: Trouble with call symput

Thanks jwillis - unfortunately, that code does not quite get me where I need to be.  I am able to get the same SAS log output as you pasted above, but this code does not result in the creation of three global macro variables (macrovariable1-macrovariable3).

Solution
‎05-07-2014 03:00 PM
Regular Contributor
Posts: 217

Re: Trouble with call symput

Chuakp,

If you look in my log, my code produced three local macro variables. If you need the macro variables to be global, then simply add a statement to define them as such "%global Macrovariable&i." immediately after the do i=1 to 3 statement.  It worked for me.

Frequent Contributor
Posts: 82

Re: Trouble with call symput

Thanks! This worked.

Frequent Contributor
Posts: 82

Re: Trouble with call symput

Using your code, I've been able to set global macro variables (where macrovariable1 = 78060, macrovariable2 = 7784, etc.).  I'm trying to figure out the right way to reference these macro variables in a %do loop.  

%macro admissiondx;

%do j=1 %to 100;

       data codes;

       if admit_dx = "&macrovariable&j." then flag = 1;   /*I want this to read: if admit_dx = "78060" then flag = 1;*/

       if flag > 0 then output;

       drop flag;

       run;

%end;

%mend admissiondx;

When I run the above code, I get a warning from SAS: "WARNING: Apparent invocation of macro MACROVARIABLE1 not resolved."  I feel like there's some small change in syntax that I need to make but can't figure it out.  Do you have any ideas?  Thanks in advance - you've been really helpful and I appreciate it. 

Regular Contributor
Posts: 217

Re: Trouble with call symput

Chuakp,

1. Add this anywhere in your code before #2.

%let mv = macrovariable;

2. Change this: if admit_dx = "&macrovariable&j."      to this:    if admit_dx = "&&&mv.&j."

3. Test #2 with this anywhere after #2.

%put "macrovariable&j. = &&&mv.&j.";

Super User
Super User
Posts: 6,499

Re: Trouble with call symput

Sounds like it would be better to make a format than a series of macro variables.

Respected Advisor
Posts: 3,777

Re: Trouble with call symput

You don't need the macro loop and WHERE to create a macro variable from each observation of DXCODE data.  Also use SYMPUTX to make the variable global if that's what you need.

data dx;
   input DXCODE $  NUMBER;
   cards;
78060          1
7784            2
09989          3
;;;;
   run;
data _null_;
  
set dx;
   call symputX(cats('macrovar',number),dxcode,'GLOBAL');
   run;
%put _global_;
Frequent Contributor
Posts: 82

Re: Trouble with call symput

Thanks for the tip.

☑ This topic is SOLVED.

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

Discussion stats
  • 11 replies
  • 376 views
  • 0 likes
  • 5 in conversation