BookmarkSubscribeRSS Feed
tomrvincent
Rhodochrosite | Level 12

I've seen some discussions of age calculation (especially when 2/28, 2/29 and 3/1 are involved)...here's my solution:

 

%macro age (bday, eday);

      INTCK('YR', &bday, &eday)-((put(&eday,mmddyyb4.)<(put(&bday,mmddyyb4.))))

%mend age;

 

It can then be called:

 

proc sql;select *,%age(BIRTH_DT, CLAIM_RECD_DT) as age from xdata;

 

-or-

 

data xxx; set xdata; age=%age(BIRTH_DT, CLAIM_RECD_DT); run;

10 REPLIES 10
novinosrin
Tourmaline | Level 20

I think the best bet for age and the most robust is using 

 

YRDIF Function

 

\http://support.sas.com/documentation/cdl/en/lefunctionsref/63354/HTML/default/viewer.htm#p1pmmr2dtec...

 

handles leap years too

tomrvincent
Rhodochrosite | Level 12

I wish it did, but it doesn't.

 

birthday of 02/29/1960, date of 02/27/1965: yrdif gives 4.997260274, which is wrong. Should be 4.

 

birthday of 02/29/1960, date of 02/28/1965: yrdif gives 5, which is wrong.  Should also be 4.

 

That's why I came up with the macro.

novinosrin
Tourmaline | Level 20

Ok, looks like you are looking for actuals with an int

 

data w;
age=int(yrdif('29feb1960'd, '27feb1965'd, 'ACT/ACT'));
age1=int(('27feb1965'd-'29feb1960'd)/365.25);
age2=int(yrdif('29feb1960'd, '28feb1965'd, 'ACT/ACT'));
age3=int(('28feb1965'd-'29feb1960'd)/365.25);
put _all_;
run;

 

 

tomrvincent
Rhodochrosite | Level 12
That works as well! I will present that to management as an alternative. Thanks!
tomrvincent
Rhodochrosite | Level 12
but age4=int(yrdif('29Mar1960'd, '29Mar1965'd, 'ACT/ACT')); gives 4 instead of 5.
Reeza
Super User

Any reason to not create a function instead of a macro here?


@tomrvincent wrote:

I've seen some discussions of age calculation (especially when 2/28, 2/29 and 3/1 are involved)...here's my solution:

 

%macro age (bday, eday);

      INTCK('YR', &bday, &eday)-((put(&eday,mmddyyb4.)<(put(&bday,mmddyyb4.))))

%mend age;

 

It can then be called:

 

proc sql;select *,%age(BIRTH_DT, CLAIM_RECD_DT) as age from xdata;

 

-or-

 

data xxx; set xdata; age=%age(BIRTH_DT, CLAIM_RECD_DT); run;


 

tomrvincent
Rhodochrosite | Level 12
You can't use a function in proc sql.
Reeza
Super User
age=intck('Year', '29feb1960'd, '27feb1965'd, 'C');

 

https://blogs.sas.com/content/sasdummy/2011/07/12/computing-age-in-sas-9-3/

 


@tomrvincent wrote:

I've seen some discussions of age calculation (especially when 2/28, 2/29 and 3/1 are involved)...here's my solution:

 

%macro age (bday, eday);

      INTCK('YR', &bday, &eday)-((put(&eday,mmddyyb4.)<(put(&bday,mmddyyb4.))))

%mend age;

 

It can then be called:

 

proc sql;select *,%age(BIRTH_DT, CLAIM_RECD_DT) as age from xdata;

 

-or-

 

data xxx; set xdata; age=%age(BIRTH_DT, CLAIM_RECD_DT); run;


 

tomrvincent
Rhodochrosite | Level 12

yeah..I've looked at that...it doesn't work either.  Birthday of 29FEB1952 and event day of 28FEB2017 should be 64, not 65.

 

I didn't just arbitrarily come up with that macro...I compared various combinations of yrdif, intck and so on but they don't correctly handle the 29/28 case.

Doc_Duke
Rhodochrosite | Level 12

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 10 replies
  • 2413 views
  • 0 likes
  • 4 in conversation