Hi all.
I've hit a snag where my macro variables resolve correctly, but seem to resolve to a list in-between, causing incorrect output and an invalid statement.
The below is what I'm currently trying:
option mprint symbolgen mlogic;
%macro test;
%let LAG_VARS = TEST_LAG_VAR_1_ TEST_LAG_VAR_2_;
%let LAG_VARS_count = 2;
%let LAG_VARS0 = 1;
%let LAG_VARS1 = TEST_LAG_VAR_1_;
%let LAG_VARS2 = TEST_LAG_VAR_2_;
%let LAG_MONTHS_count = %nrquote(1);
%let LAG_MONTHS = %nrquote(12);
%let LAG_MONTHS1 = %nrquote(12);
%if &LAG_VARS_count > 0 %then %do;
%do lag_months_loop=1 %to &LAG_MONTHS_count;
data extract_lag_3;
%do lag_vars_loop=1 %to &LAG_VARS_count;
&&lag_vars&lag_vars_loop.._L&&LAG_MONTHS&lag_months_loop..=&&lag_vars&lag_vars_loop..;
%end;
%end;
%end;
%mend;
%test;
produces the following log:
MLOGIC(TEST): Beginning execution.
MLOGIC(TEST): %LET (variable name is LAG_VARS)
MLOGIC(TEST): %LET (variable name is LAG_VARS_COUNT)
MLOGIC(TEST): %LET (variable name is LAG_VARS0)
MLOGIC(TEST): %LET (variable name is LAG_VARS1)
MLOGIC(TEST): %LET (variable name is LAG_VARS2)
MLOGIC(TEST): %LET (variable name is LAG_MONTHS_COUNT)
MLOGIC(TEST): %LET (variable name is LAG_MONTHS)
MLOGIC(TEST): %LET (variable name is LAG_MONTHS1)
SYMBOLGEN: Macro variable LAG_VARS_COUNT resolves to 2
2 The SAS System 13:23 Friday, July 20, 2018MLOGIC(TEST): %IF condition &LAG_VARS_count > 0 is TRUE
SYMBOLGEN: Macro variable LAG_MONTHS_COUNT resolves to 1
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
MLOGIC(TEST): %DO loop beginning; index variable LAG_MONTHS_LOOP; start value is 1; stop value is 1; by value is 1.
MPRINT(TEST): data extract_lag_3;
SYMBOLGEN: Macro variable LAG_VARS_COUNT resolves to 2
MLOGIC(TEST): %DO loop beginning; index variable LAG_VARS_LOOP; start value is 1; stop value is 2; by value is 1.
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable LAG_VARS_LOOP resolves to 1
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable LAG_MONTHS_LOOP resolves to 1
SYMBOLGEN: Macro variable LAG_VARS1 resolves to TEST_LAG_VAR_1_
SYMBOLGEN: Macro variable LAG_MONTHS1 resolves to 12
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
NOTE: Line generated by the macro variable "LAG_MONTHS1".
45 TEST_LAG_VAR_1__L12
_________________
180
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable LAG_VARS_LOOP resolves to 1
SYMBOLGEN: Macro variable LAG_VARS1 resolves to TEST_LAG_VAR_1_
MPRINT(TEST): TEST_LAG_VAR_1__L12=TEST_LAG_VAR_1_;
MLOGIC(TEST): %DO loop index variable LAG_VARS_LOOP is now 2; loop will iterate again.
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable LAG_VARS_LOOP resolves to 2
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable LAG_MONTHS_LOOP resolves to 1
SYMBOLGEN: Macro variable LAG_VARS2 resolves to TEST_LAG_VAR_2_
SYMBOLGEN: Macro variable LAG_MONTHS1 resolves to 12
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
NOTE: Line generated by the macro variable "LAG_MONTHS1".
45 TEST_LAG_VAR_2__L12
_________________
180
SYMBOLGEN: && resolves to &.
SYMBOLGEN: Macro variable LAG_VARS_LOOP resolves to 2
SYMBOLGEN: Macro variable LAG_VARS2 resolves to TEST_LAG_VAR_2_
MPRINT(TEST): TEST_LAG_VAR_2__L12=TEST_LAG_VAR_2_;
MLOGIC(TEST): %DO loop index variable LAG_VARS_LOOP is now 3; loop will not iterate again.
MLOGIC(TEST): %DO loop index variable LAG_MONTHS_LOOP is now 2; loop will not iterate again.
MLOGIC(TEST): Ending execution.
ERROR 180-322: Statement is not valid or it is used out of proper order.
It feels like it's resolving it in such a way that it outputs a list somehow.
Any idea how to resolve this?
Many thanks -JJ
Seems like it was a simple fix!
i stumbled upon this post https://communities.sas.com/t5/SAS-Procedures/macro-variable-resolution-ampersand-with-underscore/m-... that used %unquote(). I used it in mine (and fixed the missing run;) as below:
options mlogicnest mprintnest mlogic mprint symbolgen;
%macro test;
%let LAG_VARS = TEST_LAG_VAR_1_ TEST_LAG_VAR_2_;
%let LAG_VARS_count = 2;
%let LAG_VARS0 = 1;
%let LAG_VARS1 = TEST_LAG_VAR_1_;
%let LAG_VARS2 = TEST_LAG_VAR_2_;
%let LAG_MONTHS_count = %nrquote(1);
%let LAG_MONTHS = %nrquote(12);
%let LAG_MONTHS1 = %nrquote(12);
%if &LAG_VARS_count > 0 %then %do;
%do lag_months_loop=1 %to &LAG_MONTHS_count;
data extract_lag_3;
%do lag_vars_loop=1 %to &LAG_VARS_count;
%unquote(&&lag_vars&lag_vars_loop.._L&&LAG_MONTHS&lag_months_loop..)=&&lag_vars&lag_vars_loop..;
%end;
run;
%end;
%end;
%mend;
%test;
Seems like it was a simple fix!
i stumbled upon this post https://communities.sas.com/t5/SAS-Procedures/macro-variable-resolution-ampersand-with-underscore/m-... that used %unquote(). I used it in mine (and fixed the missing run;) as below:
options mlogicnest mprintnest mlogic mprint symbolgen;
%macro test;
%let LAG_VARS = TEST_LAG_VAR_1_ TEST_LAG_VAR_2_;
%let LAG_VARS_count = 2;
%let LAG_VARS0 = 1;
%let LAG_VARS1 = TEST_LAG_VAR_1_;
%let LAG_VARS2 = TEST_LAG_VAR_2_;
%let LAG_MONTHS_count = %nrquote(1);
%let LAG_MONTHS = %nrquote(12);
%let LAG_MONTHS1 = %nrquote(12);
%if &LAG_VARS_count > 0 %then %do;
%do lag_months_loop=1 %to &LAG_MONTHS_count;
data extract_lag_3;
%do lag_vars_loop=1 %to &LAG_VARS_count;
%unquote(&&lag_vars&lag_vars_loop.._L&&LAG_MONTHS&lag_months_loop..)=&&lag_vars&lag_vars_loop..;
%end;
run;
%end;
%end;
%mend;
%test;
I have to ask, why are you trying to do all this in macro in the first place? Base SAS is the programming language, you have just used messy macro to generate Base SAS? I mean just at a guess you could reduce your code by using lag() function, or retained variables, the do loop can be in plain datastep, and the whole macro test bit seems just there to allow a %do loop, which datastep can do with do. Admittedly its very hard to read that code with all the mixed case coding and &&&&'s.
@RW9 The above code is actually (an altered) part of a custom transform in DI Studio, hence the use of the macros to cater for the variable amount of attributes that can be lagged by variable amounts.
I've actually moved the do loop into the rename statement.
A lot is left out of the posted code to focus on the resolution issue that I had.
if you have another method that would slot nicely into a custom transform, I'd definitely be interested in seeing it,
Thanks for the interest in the question!
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: