Hello, I'm using IML inside of a macro (found a few threads here about the topic, but nothing worked). The IML code authored by Rick Wicklin works flawlessly. I inserted this code inside of a macro, and although the macro loops, IML values are static with the first loop. Rick Wicklin addresses a very similar issue here: https://blogs.sas.com/content/iml/2013/06/19/macros-and-loops.html. The crux of the matter seems to be that the interactive nature of IML behaves quite differently than a traditional data step. I've tried, promise, but just can't get it done. I am grateful for any suggestions. Code is below. Thank you, Rick Francis
OPTIONS SOURCE SOURCE2 MACROGEN MPRINT; %MACRO combination; data comb_1; set untrimmed (keep=group lag2cvrank lag2cfo_ts lagcfo_ts); if group=&I and lag2cvrank eq &J; *keep group lagcvrank gvkey; proc iml; *XY = {1 9, 2 15, 3 19, 4 20, 10 45, 12 55, 18 78, /* 7 data points used by Sen (1968) */ 12.5 30, 4.5 50}; /* 2 outliers (not considered by Sen) */ use work.untrimmed; read all var {lag2cfo_ts lagcfo_ts group lag2cvrank} into XY; close work.untrimmed; *XY = {lag2cfo_ts lagcfo_ts}; /* Theil uses all "N choose 2" combinations of slopes of segments. Assume that the first coordinates (X) are distinct */ c = allcomb(nrow(XY), 2); /* all "N choose 2" combinations of pairs */ group = XY[1,3]; lag2cvrank = XY[1,4]; Pt1 = XY[c[,1],]; /* extract first point of line segments */ Pt2 = XY[c[,2],]; /* extract second point of line segments */ slope = (Pt1[,2] - Pt2[,2]) / (Pt1[,1] - Pt2[,1]); /* Careful! Assumes x1 ^= x2 */ m = median(slope); b = median( XY[,2] - m*XY[,1] ); /* median(y-mx) */ *group=XY[c[,3],]; *lag2cvrank=XY[c[,4],]; print (b||m)[c={'Intercept' 'Slope'} L="Method=Theil Combs=All"]; print (XY); create perm1.ts_1_&I&J var {m b group lag2cvrank}; /** create data set **/ append; /** write data in vectors **/ close perm1.ts_1_&I&J ; /** close the data set **/ %MEND combination; %MACRO LOOP; %DO I=1991 %TO 1991; %DO J=0 %TO 4; %combination; %END; %END; %MEND LOOP; %LOOP; run;
Problem solved. A simple USE statement qualified with WHERE does the trick. This eliminates the data step. Thanks to everyone for your comments! Rick
Sorry, used the HTML feature. SAS code below. Thank you. Rick
OPTIONS SOURCE SOURCE2 MACROGEN MPRINT;
%MACRO combination;
data comb_1;
set untrimmed (keep=group lag2cvrank lag2cfo_ts lagcfo_ts);
if group=&I and lag2cvrank eq &J;
*keep group lagcvrank gvkey;
proc iml;
*XY = {1 9, 2 15, 3 19, 4 20, 10 45, 12 55, 18 78, /* 7 data points used by Sen (1968) */
12.5 30, 4.5 50}; /* 2 outliers (not considered by Sen) */
use work.untrimmed;
read all var {lag2cfo_ts lagcfo_ts group lag2cvrank} into XY;
close work.untrimmed;
*XY = {lag2cfo_ts lagcfo_ts};
/* Theil uses all "N choose 2" combinations of slopes of segments.
Assume that the first coordinates (X) are distinct */
c = allcomb(nrow(XY), 2); /* all "N choose 2" combinations of pairs */
group = XY[1,3];
lag2cvrank = XY[1,4];
Pt1 = XY[c[,1],]; /* extract first point of line segments */
Pt2 = XY[c[,2],]; /* extract second point of line segments */
slope = (Pt1[,2] - Pt2[,2]) / (Pt1[,1] - Pt2[,1]); /* Careful! Assumes x1 ^= x2 */
m = median(slope);
b = median( XY[,2] - m*XY[,1] ); /* median(y-mx) */
*group=XY[c[,3],];
*lag2cvrank=XY[c[,4],];
print (b||m)[c={'Intercept' 'Slope'} L="Method=Theil Combs=All"];
print (XY);
create perm1.ts_1_&I&J var {m b group lag2cvrank}; /** create data set **/
append; /** write data in vectors **/
close perm1.ts_1_&I&J ; /** close the data set **/
%MEND combination;
%MACRO LOOP;
%DO I=1991 %TO 1991;
%DO J=0 %TO 4;
%combination;
%END;
%END;
%MEND LOOP;
%LOOP;
run;
If any of the statments like
*XY = {lag2cfo_ts lagcfo_ts};
are supposed to be comments then you should change them to either Macro comments
%*XY = {lag2cfo_ts lagcfo_ts};
or block comments (careful, don't nest these)
/*XY = {lag2cfo_ts lagcfo_ts};*/
Or remove the statements entirely.
The non-macro comment statement can still attempt to execute inside a macro with usually poor results.
Problem solved. A simple USE statement qualified with WHERE does the trick. This eliminates the data step. Thanks to everyone for your comments! Rick
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.