DATA Step, Macro, Functions and more

Why doesn't this macro work?

Accepted Solution Solved
Reply
New Contributor
Posts: 3
Accepted Solution

Why doesn't this macro work?

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;


Accepted Solutions
Solution
‎03-13-2017 05:00 AM
Super User
Posts: 7,809

Re: Why doesn't this macro work?

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;
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers

View solution in original post


All Replies
Solution
‎03-13-2017 05:00 AM
Super User
Posts: 7,809

Re: Why doesn't this macro work?

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;
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
New Contributor
Posts: 3

Re: Why doesn't this macro work?

Posted in reply to KurtBremser

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!!!

Super User
Posts: 7,809

Re: Why doesn't this macro work?

[ Edited ]

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 Smiley Wink

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 7,809

Re: Why doesn't this macro work?

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.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
SAS Super FREQ
Posts: 8,866

Re: Why doesn't this macro work?

Posted in reply to KurtBremser
Hi:
Just to chime in. Kurt is correct when he says that the Macro Language and Macro Facility do not DO anything except generate code that goes forward to the compiler. By the time your code gets to the compiler and gets executed, there are NOT any % or & left in the code.

This is the reason, in our Macro classes, we recommend that students start with a basic, working SAS program, without any macro variable or macro program references. Then, they work backward from a program that works, to "macro-tize" it -- first replacing data variables and pieces of DATA step and procedure statements with macro variable references and then after the changed program works with macro variable references, turning your program into a macro program definitions with %DO loops and %IF statement to control the conditional creation of SAS code.

These papers outline the basic concepts and workings of the Macro Facility:
http://www2.sas.com/proceedings/sugi28/056-28.pdf and
https://support.sas.com/resources/papers/proceedings13/120-2013.pdf

cynthia
New Contributor
Posts: 3

Re: Why doesn't this macro work?

Posted in reply to Cynthia_sas
Hi,

Yup, i think classes and experiences is what I'm lacking of.
☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 171 views
  • 1 like
  • 3 in conversation