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

I'm fairly new to the SAS macro facility, and try to write a code that sorts variable X into quantiles.

I cannot use PROC RANK because the quantiles may not always be of identical size. So I use PROC UNIVARIATE with the option "pctlpts = &startperc1 to &endperc1 by &stepperc1 pctlpre=pf1_" to generate quantiles p1_20, ..., p1_60:


To present you my problem, I converted my macro-code into open code by deleting the "%" in front of %do, %while, and %end. I define:

%let startperc1=20;

%let endperc1=60;

%let stepperc1=20;

%let sortingvar1=X;

The code I have now is:

%let nowperc=%eval(&startperc1);

%let prevperc=%eval(&startperc1-&nowperc);

data newdata;

    set data;

    pf1_0 = 0;

    do while (%eval(&nowperc) lt %eval(&endperc1));

       if &sortingvar1>=pf1_&prevperc AND &sortingvar1<pf1_&nowperc then rank = %eval(( &nowperc - &startperc1 ) / &stepperc1 +1);   

       %let nowperc = %eval(&nowperc + &stepperc1);

       %let prevperc = %eval(&prevperc + &stepperc1);

end;

run;

This code looks extremely easy to me, and should work.... But is doesn't. Please help?

For the sake of discussion, I have generated the following fictitious data:


DATA data;

INPUT President $ Party $ X pf1_20 pf1_40 pf1_60;

DATALINES;

Adams F 2 10 20 30 40

Lincoln R 16 10 20 30 40

Grant R 18 10 20 30 40

Kennedy D 35 10 20 30 40

Adams F 4 10 20 30 40

Lincoln R 17 10 20 30 40

Grant R 22 10 20 30 40

Kennedy D 35 10 20 30 40

Adams F 8 10 20 30 40

Lincoln R 11 10 20 30 40

Grant R 19 10 20 30 40

Kennedy D 40 10 20 30 40

;

RUN;

1 ACCEPTED SOLUTION

Accepted Solutions
data_null__
Jade | Level 19

Maybe you want %DO %WHILE.

If you don't then you have data step and macro all mixed up.

View solution in original post

2 REPLIES 2
data_null__
Jade | Level 19

Maybe you want %DO %WHILE.

If you don't then you have data step and macro all mixed up.

jwsquillace
SAS Employee

The root of the issue is that macro references are resolved once before the DATA step is compiled.

Your code attempts to change the variables referenced by changing the values of the macro variables.

This demonstrates the general idea of what I am attempting to describe.  The SAS code runs without syntax errors, but there are no guarantees that it is correct.  I will leave that to your expertise.

/* test1.sas */

DATA data;
INPUT President $ Party $ X pf1_20 pf1_40 pf1_60;
DATALINES;
Adams F 2 10 20 30 40
Lincoln R 16 10 20 30 40
Grant R 18 10 20 30 40
Kennedy D 35 10 20 30 40
Adams F 4 10 20 30 40
Lincoln R 17 10 20 30 40
Grant R 22 10 20 30 40
Kennedy D 35 10 20 30 40
Adams F 8 10 20 30 40
Lincoln R 11 10 20 30 40
Grant R 19 10 20 30 40
Kennedy D 40 10 20 30 40
;
RUN;
%let startperc1=20;
%let endperc1=60;
%let stepperc1=20;
%let sortingvar1=X;
%let nowperc=%eval(&startperc1);
%let prevperc=%eval(&startperc1-&nowperc);
data newdata;
    set data;
nowprec = &nowperc;
prevperc = &prevperc;
array pf1 (*) pf1_0 pf1_20 pf1_40 pf1_60;
pf1_0 = 0;
pnt = 1;  /* pointer for pf1 array */
do while (nowperc lt &endperc1);
   if &sortingvar1>=pf1(pnt) AND &sortingvar1<pf1(pnt + 1) then
     rank = (nowperc - &startperc1 ) / ( &stepperc1 +1);   
   nowperc + &stepperc1;
   prevperc + &stepperc1;
   pnt + 1;
end;
drop pnt pf1_0;
run;

Cheers,

Jan

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 2 replies
  • 1409 views
  • 0 likes
  • 3 in conversation