DATA Step, Macro, Functions and more

Need help with automated macro code for creating two-way interaction variables

Reply
Frequent Contributor
Posts: 81

Need help with automated macro code for creating two-way interaction variables

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

Super User
Posts: 19,868

Re: Need help with automated macro code for creating two-way interaction variables

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;
 
Frequent Contributor
Posts: 81

Re: Need help with automated macro code for creating two-way interaction variables

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

Super User
Posts: 19,868

Re: Need help with automated macro code for creating two-way interaction variables

Ok, start with the allcomb function instead of manually creating combinations.

http://blogs.sas.com/content/iml/2013/09/30/generate-combinations-in-sas.html
Respected Advisor
Posts: 4,934

Re: Need help with automated macro code for creating two-way interaction variables

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;


PG
Frequent Contributor
Posts: 81

Re: Need help with automated macro code for creating two-way interaction variables

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.

Frequent Contributor
Posts: 81

Re: Need help with automated macro code for creating two-way interaction variables

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;
Ask a Question
Discussion stats
  • 6 replies
  • 233 views
  • 0 likes
  • 3 in conversation