Hi,
This situation is when one of the condition hit (if &&nA&i <= 0), that line of data should not go throught the logic, however with the code below, it still run throught the logic.
Can anyone help to debug/refine the code below, many thanks.
DATA WORK.TESTING;
attrib acct length=$2.;
INFILE DATALINES DLM="$" DSD;
INPUT acct a1 a2 a3 a4 a5 a6 a7;
DATALINES;
A1$6$2$3$56$76$887$12
A2$4$90$89$76$887$12$12
A3$6$90$098$76$887$12$7
A4$9$20$12$76$887$23$12
A5$1$$20$23$76$887$12
;
RUN;
%macro test;
data _null_;
set work.testing end=lastrec;
remain_bl = SUM(7,-a1);
bl_value = "a"||STRIP(PUT(remain_bl,best.));
list_cnt = put(_n_,3.);
call symput('nA'||STRIP(list_cnt),remain_bl);
call symput('Avalue'||STRIP(list_cnt),bl_value);
if lastrec then call symput ('nRows',list_cnt);
run;
data output;
set testing;
%do i = 1 %to &nRows;
%put &i &&nA&i &&Avalue&i;
if _n_ = &i then do;
if &&nA&i > 0 then do;
checking = "&&Avalue&i.";
SumOf = SUM( of a1 - &&Avalue&i);
end;
else if &&nA&i <= 0 then do;
checking = "&&Avalue&i.";
SumOf = 999999;
end;
output;
end;
else do;
checking = '';
SumOf = .;
output;
end;
%end;
run;
%MEND test;
%test;
You are making calculations with a massive abuse of the macro language that can be done in one simple data step. Are you competing in the Obfuscated SAS Code Contest?
The way I see it, you are creating lookup values for all observations, that are then merged back via repetitions of code for every _n_. DEpending on those values, you do a calculation or not.
First of all, your macro code as posted does not work, as it creates invalid code that causes a syntax error:
NOTE: Line generated by the macro variable "AVALUE4". 75 a-2
That's because you have a value of a1=9, and 7-9 = -2, and you can't have a variable named a-2; so there's a logical flaw there.
Summing a subset of your variables dynamically is best done with an array:
data output;
set testing;
array vars {*} a1-a7;
remain_bl = SUM(7,-a1);
checking = "a"||STRIP(PUT(remain_bl,best.));
if remain_bl > 0 then do;
sumof = 0;
do i = 1 to a1;
sumof = sumof + vars{i};
end;
end;
else do;
SumOf = 999999;
end;
drop i;
run;
You are making calculations with a massive abuse of the macro language that can be done in one simple data step. Are you competing in the Obfuscated SAS Code Contest?
The way I see it, you are creating lookup values for all observations, that are then merged back via repetitions of code for every _n_. DEpending on those values, you do a calculation or not.
First of all, your macro code as posted does not work, as it creates invalid code that causes a syntax error:
NOTE: Line generated by the macro variable "AVALUE4". 75 a-2
That's because you have a value of a1=9, and 7-9 = -2, and you can't have a variable named a-2; so there's a logical flaw there.
Summing a subset of your variables dynamically is best done with an array:
data output;
set testing;
array vars {*} a1-a7;
remain_bl = SUM(7,-a1);
checking = "a"||STRIP(PUT(remain_bl,best.));
if remain_bl > 0 then do;
sumof = 0;
do i = 1 to a1;
sumof = sumof + vars{i};
end;
end;
else do;
SumOf = 999999;
end;
drop i;
run;
Thanks for the advice, actually the intention of the code is to use the calculated "remain_bl" to determine the stopping point of summation.
For example, if calculated remain_bl = 3, then the summation should start from SUM(of a1 - a3).
Because of the negative result returns, I have to think of another way.
Is that a competition for Obfuscated SAS cd contest? Haha.
Anyway, this code works for me. Thanks!!!
Jordan_H wrote:
Is that a competition for Obfuscated SAS cd contest? Haha.
You can see the difference between the two codepieces. It took me some time to infer your intentions from the code, while I guess my code is much easier to decipher.
Since there actually are such contests (the most famous being The International Obfuscated C Code Contest), I often use that remark when I encounter unnecessarily complicated code that is hard to read and re-engineer.
No insult intended, missed to add the 😉
Just to clarify things: with macro language you create code for exection, you do not do anything else!
That code will be there, and if it is syntactically wrong code, the data step will not compile, even if that branch wouldn't be executed at runtime.
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.