BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
pmpradhan
Quartz | Level 8

I tried to calculate age using the 

current_age=int(yrdif(b_date, today(), 'ACTUAL')); Since the age is before 1960 for bene_id 02, It is giving me negative value.

Here is my data after calculating age:

 

bene_id    b_date           Current_age

01             18May64        54

02             18Jun22         -3

03              08sep51        67

 

Any help appreciated!

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

The YEARCUTOFF option only impacts how SAS determine the century when converting text with two digit years into dates.

You are not converting any text into dates.  You already have data with the wrong century.

You might add logic to check the date for reasonableness before calculating age.

data B;
  set A;
  b_date=datepart(birthdate);
  date=today();
  if b_date > date then do;
    put b_date = @ ;
    b_date=intnx('year',b_date,-100,'s');
    put '-> ' b_date ;
  end;
  current_age=int(yrdif(b_date, date, 'ACTUAL'));
  format b_date date date9.;
run;

View solution in original post

23 REPLIES 23
novinosrin
Tourmaline | Level 20

Try:

 

Age_exact = floor((intck('month',DOB,Date)-(day(Date) < day(DOB))) / 12);

 

 

plug in: today() for date

pmpradhan
Quartz | Level 8

I used it as:

age_exact=floor((intck('month', b_date, Date)-(day(Date) < day(b_date)))/12);

 

and I saw both two new variables were empty.

novinosrin
Tourmaline | Level 20

Ok tested with your sample that you gave us. Here it is:

 

options yearcutoff=1910;
data have;
input bene_id $   b_date  :date9.;          
format b_date date9.;
cards;
01             18May64        
02             18Jun22         
03              08sep51       
;

data want;
set have;
date=today();
Age_exact = floor((intck('month',b_date,Date)-(day(Date) < day(b_date))) / 12);
format date date9.; run;
pmpradhan
Quartz | Level 8

Thanks, but I'm still getting -4 as a value for age_exact.

novinosrin
Tourmaline | Level 20

Please run the code i gave you. Here is the result. Just run and see:

 

proc print data=want noobs;run;

 

SAS Output

The SAS System

bene_id b_date date Age_exact
01 18MAY1964 12SEP2018 54
02 18JUN1922 12SEP2018 96
03 08SEP1951 12SEP2018 67
pmpradhan
Quartz | Level 8

I had created the b_date variable from the date variable birthdate(with datetime. format) using following code:

 

birthdate=datepart(b_date);
format birthdatef date.;

 

My data now looks like this after applying the code you suggested.

bene_idbirthdateb_datedateAge 
118May64:00:06:0818-May-6412-Sep-1854 
218Jun22:00:09:0318-Jun-2212-Sep-18-4 
38Sep51:00:01:068-Sep-5112-Sep-1867 
Reeza
Super User

What happens when you use a DATE9 format. I suspect you have a data integrity issue. 

Tom
Super User Tom
Super User

Your problem is not that the birth date is before 1960.  The problem is that the birth date is after 2018.

Displaying the dates with only two digits of the year is confusing you, but not SAS.

 

                               Current_    current_
Obs    bene_id       b_date      age_x        age

 1        1       18MAY1964        54          54
 2        2       18JUN1922        -3          96
 3        2       18JUN2022        -3          -3
 4        3       08SEP1951        67          67
bobpep212
Quartz | Level 8
It's not because it is before 1960. It is because it is before 1926, which is the default yearcutoff= when using date7. formats. Change the yearcutoff= option to 1910 and it works.
pmpradhan
Quartz | Level 8

thanks, any suggestion on how to handle the negative age?

ballardw
Super User

@pmpradhan wrote:

I tried to calculate age using the 

current_age=int(yrdif(b_date, today(), 'ACTUAL')); Since the age is before 1960 for bene_id 02, It is giving me negative value.

Here is my data after calculating age:

 

bene_id    b_date           Current_age

01             18May64        54

02             18Jun22         -3

03              08sep51        67

 

Any help appreciated!

 

 


The most likely issue is that your dates had 2-digit years and when you read them the YEARCUTOFF option assumed the dates you thought were 19xx were actually 20xx.

Run this code:

proc options option=yearcutoff;
run;

Check the log for the value displayed. Example from mine:

 

 YEARCUTOFF=1926   Specifies the first year of a 100-year span that is used by date informats and
                   functions to read a two-digit year.

Any year prior to 26 will be treated as 20XX.

 

Fix: either use 4 digit years or adjust the year cutoff value with

 

options yearcutoff=1920; (or similar).

Caution: if you use 1918 then any births in 2018 are in danger.

Then reread the data with the two digit years and then reset your yearcutoff option.

 

The above is one way.

 

Or you could test the year of b_date and adjust the birth date:

if year(b_date) > year(today()) then b_date=intnx('year',b_date,-100);

BEFORE calculating the age.

VDD
Ammonite | Level 13 VDD
Ammonite | Level 13

your negative value is because the second card has jun-18-2022 as the birthdate if you don't set the options yearcutoff=1910;

pmpradhan
Quartz | Level 8

Here is my result from 

proc options option=yearcutoff;
run;

 

 

 

SAS (r) Proprietary Software Release 9.4 TS1M5

YEARCUTOFF=1910 Specifies the first year of a 100-year span that is used by date informats and functions to read a two-digit
year.

VDD
Ammonite | Level 13 VDD
Ammonite | Level 13

is the 22 year 1922 or 2022.  If 1922 then the options yearcutoff=1910, works correctly.  If the person was born in 2022 then you have to wait until they are born to calculate their age.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to connect to databases in SAS Viya

Need to connect to databases in SAS Viya? SAS’ David Ghan shows you two methods – via SAS/ACCESS LIBNAME and SAS Data Connector SASLIBS – in this video.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 23 replies
  • 2277 views
  • 8 likes
  • 9 in conversation