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!!!
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
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;
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;
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
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;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.