BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Jordan_H
Calcite | Level 5

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;

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

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;

View solution in original post

6 REPLIES 6
Kurt_Bremser
Super User

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;
Jordan_H
Calcite | Level 5

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

Kurt_Bremser
Super User

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 😉

Kurt_Bremser
Super User

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.

Cynthia_sas
SAS Super FREQ
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
Jordan_H
Calcite | Level 5
Hi,

Yup, i think classes and experiences is what I'm lacking of.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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