Help using Base SAS procedures

Global macro

Reply
Frequent Contributor
Posts: 107

Global macro

Hello,

I want to create a new macro variable (year+1) based on the macro year variable (2009-2012) and apply the new macro variable to the age calculation - that is, for 2009 data, the age calculation should be based the fiscal year end, that is March 2010, etc.

   Age = INT((INTCK('month', DOB,'31mar&year2.'d) - (DAY(DOB)>DAY('31mar&year2.'d)))/12);

I thought it would work but it didn't; SAS didn't recognize the year2 variable.

Here is the macro:

%macro service_age ();

%do year=2009 %to 2011;

data list&year; merge  dob_data (in=a)   service&year (in=b); by id;

    if a and b;

    %let year2=1+&year;

    Age = INT((INTCK('month', DOB,'31mar&year2.'d) - (DAY(DOB)>DAY('31mar&year2.'d)))/12);

run;

%end;

%mend service_age;

%service_age;

If I don't use macro, it'd look like the following:

data list2009; merge  dob_data (in=a)   service2009 (in=b); by id;

    if a and b;

    Age = INT((INTCK('month', DOB,'31mar2010'd) - (DAY(DOB)>DAY('31mar2010'd)))/12);

run;

data list2010; merge  dob_data (in=a)   service2010 (in=b); by id;

    if a and b;

    Age = INT((INTCK('month', DOB,'31mar2011'd) - (DAY(DOB)>DAY('31mar2011'd)))/12);

run;

data list2011; merge  dob_data (in=a)   service2011 (in=b); by id;

    if a and b;

    Age = INT((INTCK('month', DOB,'31mar2012'd) - (DAY(DOB)>DAY('31mar2012'd)))/12);

run;

Thanks in advance for the help.

Super Contributor
Posts: 349

Re: Global macro

Hi;

Try to use double quotes...

Age = INT((INTCK('month', DOB,"31mar&year2."d) - (DAY(DOB)>DAY("31mar&year2."d)))/12);

Thanks,

Shiva

Frequent Contributor
Posts: 107

Re: Global macro

Thanks a million. It worked.

Trusted Advisor
Posts: 1,914

Re: Global macro

Macros simply aren't needed here for year2.

Instead of

'31mar&year2.'d

you could use

mdy(3,31,&year+1)

My general philosophy is not to use macros if they are not needed. Your loop involving the macro variable &year may or may not be a good use of macros, but even though I can't see your datasets, it seems to me that you don't need a macro here either.

Frequent Contributor
Posts: 107

Re: Global macro

Posted in reply to PaigeMiller

Thanks for the suggestion. I changed to using mdy and included sample data below. Let me know if there are ways to improve the code. I've 10 years of data and just use 3 here as an example.

data dob ;

input id dob $8.;

datalines;

1 19900314

2 20000413

3 20011201

4 20011201

5 20030915

;

run;

data dob_data; set dob;

format dob2 yymmdd10.;

dob2=input(dob,yymmdd10.);

drop dob;

rename dob2=dob;

run;

data service2009; input id;

datalines;

1

2

3

;

data service2010; input id;

datalines;

1

3

5

;

data service2011; input id;

datalines;

1

2

4

5

;

%macro service_age ();

%do year=2009 %to 2011;

data list&year; merge  dob_data (in=a)   service&year (in=b); by id;

    if a and b;

    %let year2=1+&year;

    Age = INT((INTCK('month', DOB,mdy(3,31,&year.+1) - (DAY(DOB)>DAY(mdy(3,31,&year.+1))))/12));

run;

%end;

%mend service_age;

%service_age;

Trusted Advisor
Posts: 1,914

Re: Global macro

I'm still not convinced that macros are needed here, but without being able to see your data, I don't know for sure.

However, the code you have should work — so it's probably a good idea to use it. You can eliminate the line that says "%let year2=1+&year;"

Ask a Question
Discussion stats
  • 5 replies
  • 276 views
  • 0 likes
  • 3 in conversation