## A simple sas macro

Solved
Frequent Contributor
Posts: 131

# A simple sas macro

Hi, I developed a simple macro as below. The purpose is to create dummy age groups based on different cut-off value.

I want to have 3 variables: age1, age2 and ag3. All these 3 variables are binary (0, 1). For example, if age < max(age) / 3, then age1 = 1, else age1=0.  Similarly for age2 and age3.  Unfortunately, the resut from PROC FREQ is wrong (all 0).

%LET n=3;

%macro threshold;
PROC SQL;
SELECT max(age) INTO:max
FROM work.data;

RUN;

DATA work.test;
SET work.data;
%DO i=1 %TO &n-1;
%IF age < &i * &max / &n   %THEN age&i=1;
%ELSE age&i=0;
%END;
%mend threshold;

%threshold

PROC FREQ DATA=work.test(obs=1000);
TABLES age1 age2 age3;
RUN;

Thanks for help.

Accepted Solutions
Solution
‎09-13-2011 10:16 AM
PROC Star
Posts: 8,163

## A simple sas macro

data data;

set sashelp.class end=eof;

output;

if eof then do age=1 to 14;

output;

end;

run;

%LET n=3;

%macro threshold;

PROC SQL;

SELECT max(age) INTO:max

FROM work.data;

quit;

/*RUN;*/

DATA work.test;

SET work.data;

%DO i=1 %TO &n;

IF age <= &i * &max / &n   THEN age&i=1;

ELSE age&i=0;

%END;

run;

%mend threshold;

%threshold

PROC FREQ DATA=work.test(obs=1000);

TABLES age1 age2 age3;

RUN;

All Replies
PROC Star
Posts: 8,163

## A simple sas macro

You mix macro and non-macro code incorrectly.  However, you don't even need a macro and I'd suggest reconsidering your design.  I could definitely be wrong, but I'd think that you really want to include minimum and maximum ages in your logic.

For example, using sashelp.class, does the following reflect what you really want to accomplish?:

data data;

set sashelp.class;

run;

%LET n=3;

PROC SQL;

SELECT min(age),max(age),max(age)-min(age)

INTO :min, :max, :range

FROM work.data

;

quit;

DATA work.test;

SET work.data;

array age_group(3);

DO i=1 TO &n.;

IF &min.+(i-1)*&range./&n.<=age<=&min.+i*&range./&n.

THEN age_group(i)=1;

ELSE age_group(i)=0;

END;

run;

PROC FREQ DATA=work.test(obs=1000);

TABLES age_group:*age;

RUN;

Frequent Contributor
Posts: 131

## A simple sas macro

I am wondering what is 'macro and non-macro code' here. Do you mean that PROC SQL is non-macro code?

If I really want to incorporate all codes (except PROC FREQ) in a single macro, what is the right answer?

Solution
‎09-13-2011 10:16 AM
PROC Star
Posts: 8,163

## A simple sas macro

data data;

set sashelp.class end=eof;

output;

if eof then do age=1 to 14;

output;

end;

run;

%LET n=3;

%macro threshold;

PROC SQL;

SELECT max(age) INTO:max

FROM work.data;

quit;

/*RUN;*/

DATA work.test;

SET work.data;

%DO i=1 %TO &n;

IF age <= &i * &max / &n   THEN age&i=1;

ELSE age&i=0;

%END;

run;

%mend threshold;

%threshold

PROC FREQ DATA=work.test(obs=1000);

TABLES age1 age2 age3;

RUN;

Frequent Contributor
Posts: 131

## A simple sas macro

Hi art, it is a good code and it worked.

I found my problem is from the %if. So I should not use %if when %do is used. Can I ask why? I have assumed that for macro code, all conditional statements (e.g., if, do) should add the '%' sign.

PROC Star
Posts: 8,163

## A simple sas macro

You can find a nice explanation of the timing considerations at: http://www2.sas.com/proceedings/sugi27/p020-27.pdf

Frequent Contributor
Posts: 131

## A simple sas macro

Thanks for sharing the resource, art.

I just found a macro code online as below. Both if and %if are used. Very confused :smileyconfused: Do you mind if please give a clue?

%macro claimsrep;

data _null_;

set claims end=eof;

count + 1;

if eof then call symput(‘count’, left(put(count,5.)));

%if &count > 0 %then %do;

%end;

%mend claimsrep;

%claimsrep

PROC Star
Posts: 8,163

## A simple sas macro

You apparently didn't notice the title of that particular exhibit in the paper it came from: "Figure 6. A Common Error"  see: http://www.nesug.org/proceedings/nesug03/bt/bt009.pdf

In short, the code won't work as written.

However, it is also a nice summary on the topic.

🔒 This topic is solved and locked.