I would like to use lubridate
to calculate age in years given their date of birth and today's date. Right now I have this:
library(lubridate)
today<-mdy(08312015)
dob<-mdy(09071982)
today-dob
which gives me their age in days.
I would like to use lubridate
to calculate age in years given their date of birth and today's date. Right now I have this:
library(lubridate)
today<-mdy(08312015)
dob<-mdy(09071982)
today-dob
which gives me their age in days.
This is the lubridate
approach I would take:
interval(dob, today) / years(1)
Yields the answer of 32
years.
Note that the function will complain that it cannot express the remainder of the fraction of the year. This is because year is not a fixed concept, i.e. 366 in leap years and 365 in non-leap years. You can get an answer with more detail in regard to the number of weeks and days:
interval_period = interval(dob, today)
full_year = interval_period %/% years(1)
remaining_weeks = interval_period %% years(1) %/% weeks(1)
remaining_days = interval_period %% years(1) %% weeks(1) %/% days(1)
sprintf('Your age is %d years, %d weeks and %d days', full_year, remaining_weeks, remaining_days)
# [1] "Your age is 32 years, 51 weeks and 1 days"
Note that I use %/%
for division and %%
as modulo to get the remaining weeks/days after subtracting the full years/weeks.
This is an old question, but I still missing the following clean approach. (Tidyverse is only necessary for the %>%
operator.)
library(tidyverse)
library(lubridate)
today<-mdy(08312015)
dob<-mdy(09071982)
interval(dob, today) %>%
as.numeric('years')
# 32.98015 - you have to decide how to deal with the fraction of a year
as.duration(interval(dob,today)) %/% as.duration(years(1))
should do the job without errors.
as.period(today - dob, unit = "years")
This will give a message that it's only an estimate because it doesn't take into account the exact starting date and end date.
Another Tidyverse approach (with the shortest amount of code) would be
library(tidyverse)
library(lubridate)
today<-mdy(08312015)
dob<-mdy(09071982)
dob %--% today / ddays(365.25)
Another answer, it's much faster. See speed test below
as.numeric(today - dob) / 365.25
Comparing all the answers
library(dplyr)
library(lubridate)
today<-mdy(08312015)
dob<-mdy(09071982)
interval(dob, today) / years(1)
> 32.98082
as.duration(interval(dob,today)) %/% as.duration(years(1))
> 32
interval(dob, today) %>% as.numeric('years')
> 32.98015
dob %--% today / ddays(365.25)
> 32.98015
as.numeric(today - dob) / 365.25
> 32.98015
I'm not sure whether 32.98082
or 32.98015
is more correct. See https://stackoverflow.com/a/32313487/4745348
Speed test
microbenchmark::microbenchmark(
interval(dob, today) / years(1),
as.duration(interval(dob,today)) %/% as.duration(years(1)),
interval(dob, today) %>% as.numeric('years'),
dob %--% today / ddays(365.25),
as.numeric(today - dob) / 365.25
)
> Unit: microseconds
> expr min lq mean median uq max neval
> interval(dob, today)/years(1) 1913.601 1996.1510 2172.96001 2059.1005 2102.851 6037.201 100
> as.duration(interval(dob, today))%/%as.duration(years(1)) 749.700 799.1010 912.30394 823.1510 863.751 5078.601 100
> interval(dob, today) %>% as.numeric("years") 439.701 464.0510 485.31708 480.3010 501.101 591.000 100
> dob %--% today/ddays(365.25) 394.501 427.5510 450.37502 443.7010 463.301 620.601 100
> as.numeric(today - dob)/365.25 17.400 25.9005 30.66293 32.7515 36.151 52.700 100