macro change multiple variables

Accepted Solution Solved
Reply
Contributor
Posts: 30
Accepted Solution

macro change multiple variables

Hi - 

 

I want to write a macro for a if then command to create a series of dummy varibales, my code looks like this:

%macro change(var);
data want;
   set data;
   if Q07&var. = 4 or Q07&var. = 5 then dissatisfy&var. = 1;
   else dissatisfy&var. = 0;
run;
%mend;
%change(f);
%change(h);
%change(b);
%change(a);
%change(e);
%change(i);
%change(d);
%change(g);
%change(c);
%change(j);
%change(k);

The ideal new dummy variables woule be: dissatisfyf dissatisfyh dissatisfyb....dissatisfyk. However, when I runned this, I could just get dissatisfyk. 

Do you know what's wrong?

 

Thanks!!!


Accepted Solutions
Solution
‎07-24-2017 11:38 AM
Regular Contributor
Posts: 227

Re: macro change multiple variables

1. your code creates the same data set for each macro call

that's why you get the results of only the last call.

Check your log to see:

DATA want;

q07a = ...;

DATA want;

q07b = ...;

 

2. macro  is not necessary here

learn how to use arrays

 

DATA want;

array _q (*) q07a -- q07h;*may have to list q07a q07b q07c ....;

array _d(*) disa -- dish;*names must align with above;

set data;

do _i = 1 to dim(_q);

   _d(_i) = (_d(_i)  eq 4

          or _d(_i)  eq 5);

   end;

 

Ron Fehd not always macro-needed maven

 

View solution in original post


All Replies
Super User
Posts: 19,789

Re: macro change multiple variables

You always start from the same data set. In this case, your previous runs are not saved, only the last run.

 

data want; *-> Created new each time from data - previous data not kept;
   set data;
   if Q07&var. = 4 or Q07&var. = 5 then dissatisfy&var. = 1;
   else dissatisfy&var. = 0;
run;

 

Keep the dataset name the same or instead, use an array may simplify this a lot.  Other option is to use a format.  I would strongly recommend looking at the automated ways of creating dummy variables such as using GLMMOD. And depending on the PROC, it may handle it already, these procs would include Logistic, GLM, PHREG. 

 

data want; *-> Created new each time from data - previous data not kept;
   set want;
   if Q07&var. = 4 or Q07&var. = 5 then dissatisfy&var. = 1;
   else dissatisfy&var. = 0;
run;
Trusted Advisor
Posts: 1,913

Re: macro change multiple variables

[ Edited ]

yes, I know what is happening ... each time you run the program, you create a new data set named WANT, which erases previous data sets named WANT, and so the last time you run the program, the variable in WANT is dissatisfyk.

 

This can all be avoided by not using macros here, but instead using an ARRAY statement or two, something like (UNTESTED CODE)

 

array q07 q07a q07b q07c /* I'm not going to type them all */ ;
array dis dissatisfya dissatisfyb dissatisfyc;
do I=1 to dim(q07);
     if q07(I)=4 or q07(I)=5 then dis(I)=1; else dis(I)=0;
end;
Solution
‎07-24-2017 11:38 AM
Regular Contributor
Posts: 227

Re: macro change multiple variables

1. your code creates the same data set for each macro call

that's why you get the results of only the last call.

Check your log to see:

DATA want;

q07a = ...;

DATA want;

q07b = ...;

 

2. macro  is not necessary here

learn how to use arrays

 

DATA want;

array _q (*) q07a -- q07h;*may have to list q07a q07b q07c ....;

array _d(*) disa -- dish;*names must align with above;

set data;

do _i = 1 to dim(_q);

   _d(_i) = (_d(_i)  eq 4

          or _d(_i)  eq 5);

   end;

 

Ron Fehd not always macro-needed maven

 

Super User
Super User
Posts: 7,042

Re: macro change multiple variables

Just turn on the MPRINT option and look at the generated code. You will see that you keep overwriting the target dataset so only the last call has any effect. You have basically put your macro loop in the wrong place. You want to loop INSIDE of a single data step to create multiple variables in that data step.

 

But you really don't need macro code for this problem.  Just use arrays.

Let's call your input dataset HAVE instead of DATA to avoid confusion the the DATA statement.  Also let's make your new variable names using numeric suffix instead of letter suffixes to save a lot of typing.

Also we can take advantage of how SAS evaluates boolean expressions to 1 or 0 to simplify the code by replacing the IF/THEN/ELSE construct with a simple assignment statement.

 

data want;
   set have;
   array old Q07a Q07b Q07c Q07d Q07e Q07f Q07g Q07h Q07i Q07j Q07k;
   array new dissatisfy1 - dissatisfy11 ;
   do i=1 to dim(old);
     new(i) = old(i) in (4,5);
   end;
run;
☑ This topic is solved.

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

Discussion stats
  • 4 replies
  • 192 views
  • 6 likes
  • 5 in conversation