Working with the following toy dataset, I'm trying to create code which will automatically calculate two-way interaction variables for a given set of main effects named "black", "white" and "red".
data test;
input black white red;
cards;
10 20 30
40 50 60
70 80 90
;
run;
proc contents data=test out=varlist(keep=name);
run;
data _null_;
length allvars $20;
retain allvars ' ';
set varlist end=eof;
allvars = trim(left(allvars))||' '||left(name);
if eof then call symput('varlist', allvars);
run;
%put &varlist;
/*
black red white
*/
%macro create_interaction_vars();
data test;
set test;
%let separator_s =%str( );
%do i=1 %to 3;
%let v&i = %scan(&varlist, &i, %str( ));
%end;
%do i=1 %to 3;
%do j=1 %to 3;
%if &i <= &j %then %goto continue;
data test;
set test;
w&i.&j = &&v&i.*&&v&j;
rename w&i.&j = "&v&i._&v&j_int";
run;
%continue:
%end;
%end;
run;
%mend;
%create_interaction_vars();
I have no problems creating interactions variables named w12, w13, and w23. However, I'd like the interaction terms to have more informative names created from the main effect terms such as: "white_red_int", "white_black_int", and "red_black_int", but am getting tied up when it comes to concatenating two macro variable names.
Any help is much appreciated, thanks!
Robert
Are you familiar with the SAS shortcut notation for creating two way interactions.
You can use the | with @N to create your two way interactions. I can't find the documentation but I'm sure it's in there somewhere.
Here's an example using SASHELP.CARS
proc glm data=sashelp.cars;
model weight = invoice | length | mpg_city | mpg_highway @2;
run;
Reeza -
Yes, I've used that feature and it's quite handy.
In this case I have a lot of variables & the dataset will be exported to a text file for analysis in other programs. Otherwise I'd use the | and n@ option.
Robert
You can build on @Reeza's suggestion with proc GLMMOD and get your design matrix directly into a dataset. Just add your dependent variable to your dataset :
data test;
input id green black white red;
cards;
1 2.1 10 20 30
2 3.2 40 50 60
3 4.3 70 80 90
;
proc glmmod data=test outdesign=testd outparm=testp;
model green = black | white | red @2 / noint;
weight id; /* Just copy this variable */
run;
proc sql;
select
cats("Col", _COLNUM_, "=", translate(EFFNAME, "_", "*")),
cats("Col", _COLNUM_, "=""", EFFNAME, """")
into :renameVars separated by " ", :labelVars separated by " "
from testp;
quit;
data myDesign;
set testd;
rename &renameVars;
label &labelVars;
run;
proc print data=myDesign noobs label; run;
Thanks PGStats, this works great!
There must still be a way to combine two macro variable names like "black" and "white" into a single varibale name "black_white_int", but getting the macro code syntax right with the ampersands and quotation marks has always been tricky for me.
Here's another solution to creating interaction variables that avoids macro programming.
Create a variable list of the main effects of interest from proc contents, then accumulate all of the interaction variable creation data step statements into one long macro variable.
For example, to create the interaction variables green_red_int, black_red_int, and white_red_int, run the following code:
data test;
input id green black white red;
cards;
1 2.1 10 20 30
2 3.2 40 50 60
3 4.3 70 80 90
;
proc contents data=test out=varlist(keep=varnum name) order=varnum;
run;
proc sort data=varlist;
by varnum;
run;
data varlist;
set varlist;
if varnum in(2:4);
run;
data _null_;
length allvars $90;
retain allvars;
set varlist end=eof;
allvars =trim(left(allvars))||' '||trim(name)||'_red_int = '||trim(name)||'*red;';
if eof then call symput('interactions', allvars);
run;
%put &interactions;
data test2;
set test;
&interactions;
run;
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.
Ready to level-up your skills? Choose your own adventure.