Date: Thu, 21 Jul 2011 01:49:21 -0700
Reply-To: Mark Miller <mdhmiller@GMAIL.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Mark Miller <mdhmiller@GMAIL.COM>
Subject: Re: Figuring out Age in Years, Months and Days
In-Reply-To: <OF7BF1D843.90D28D8F-ON0A2578D3.007504AF-0A2578D3.00761ECA@kp.org>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
John,
Short calendar durations are not the real problem.
Trick seems to me to be how to deal with
the heterogeneous mixture of units.
One year has exactly 12 months.
But every year does not have equal number of WHOLE weeks.
Nor does every month does not have equal nbr of weeks or days.
Anyway...the puzzle aspect interested me so I put together
a crude program which appears to me to work.
This was my third try. Program is below my sig.
Has inline test data which include some 0,1,2 day lives
as well as some leap year cases.
... Mark Miller
*---------------------------------;
DATA age_as_yymmwwdd;
input BirthDate yymmdd10. DeathDate yymmdd10. ;
Span_year = intck('YEAR', BirthDate, DeathDate ) ;
Span_mon = intck('MONTH', BirthDate, DeathDate ) ;
Span_week = intck('WEEK', BirthDate, DeathDate ) ;
Span_day = intck('DAY', BirthDate, DeathDate ) ;
** These will hold the Age components ;
rem_Years = 0; rem_Months= 0; rem_Weeks = 0; rem_Days = 0;
DivYear = (DeathDate - BirthDate) /365.242199 ;
floorYear = floor(DivYear) ;
floorDays = intck('YEAR', BirthDate, DeathDate ) - int(floorYear*365.25);
rem_Years = min(floorYear, intck('YEAR', BirthDate, DeathDate )) ;
YYdt = intnx('year', BirthDate, rem_Years, "sameday" );
IF YYdt > DeathDate THEN DO;
rem_Years = max( 0, rem_Years -1 );
YYdt = intnx('year', BirthDate, rem_Years, "sameday" );
END;
rem_months = intck('month', YYdt, DeathDate );
MMdt = intnx('month', YYdt, rem_months, "sameday");
IF MMdt > DeathDate THEN DO;
rem_months = max( 0, rem_months -1 );
MMdt = intnx('month', YYdt, rem_months, "sameday") ;
END;
mon_rem_days = DeathDate - MMdt ;
mon_div_weeks = int(mon_rem_days / 7 );
mon_mod_days = mon_rem_days - (mon_div_weeks * 7 ) ;
rem_Weeks = mon_div_Weeks ;
rem_Days = mon_mod_days ;
format BirthDate DeathDate YYdt MMdt yymmdd10. ;
format Span: rem: DivYear 11.6 mon_: 8.0;
DATALINES4;
19131230 19131230
19131230 19131231
19131231 20110601
19140101 20110602
19140201 19140202
19140201 19140206
19140201 19140207
19140201 19140208
19140201 19140228
19440111 20100103
19450627 20110627
19451012 20110512
19451012 20110511
19451012 20110513
19990227 20000228
19990227 20000229
20000201 20000229
20000201 20000301
20000228 20010227
20000229 20010301
20071012 20100421
20071012 20081011
20071012 20081012
20071012 20081013
20071012 20081014
20071012 20071021
20071012 20071029
20011221 20020102
;;;;
proc sort; by Span_day rem_years; run;
Proc print; VAR BirthDate DeathDate DivYear rem: ; run;
On 7/20/2011 2:30 PM, John Parker wrote:
> Hi All,
>
> I have a requirement to figure out Age at Death and it has to be expressed
> in Years, Months, Weeks and Days.
>
> This is to accommodate individuals who may have died a short period after
> childbirth, etc.
>
> In the past I have used code like this:
>
> Age_at_death=%calcage(birth_date, death_date);
>
> %macro CalcAge(BDtVar, RefDate) ;
>
> floor ((intck('month',&BDTVar,&RefDate) - (day(&RefDate)< day(&BDTVar)))
> / 12)
>
> %mend CalcAge ;
>
> The DOB and DOD variables are formatted as MMDDYY10.
>
> Has anyone done this type of calculation to this degree?
>
> Many Thanks!
>
> John