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

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
  • 10 replies
  • 1147 views
  • 0 likes
  • 4 in conversation