我想使用lubridate
来计算一个人的年龄,根据他们的出生日期和今天的日期。目前我的代码是这样的:
library(lubridate)
today<-mdy(08312015)
dob<-mdy(09071982)
today-dob
它会给我他们的年龄(以天为单位)。
这是我会采用的lubridate
方法:
interval(dob, today) / years(1)
产生答案为 32
年。
请注意,该函数会抱怨它不能表达年份的余数部分,这是因为年份不是一个固定的概念,即在闰年中为366天,在非闰年中为365天。您可以得到更详细的答案,涉及到周数和天数:
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"
请注意,我使用%/%
来表示除法,%%
表示取模运算,以获得减去整年/整周后剩余的周数/天数。
new_interval
已被弃用,请改用interval
。 - dpelnew_interval
已被弃用,现在只需使用interval
。 - MS Berends这是一个老问题,但我仍然缺少以下简洁的方法。(Tidyverse 仅对 %>%
运算符是必需的。)
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.numeric("years")
如何针对 interval()
的输出进行工作? - Emmanas.duration(interval(dob,today)) %/% as.duration(years(1))
as.period(today - dob, unit = "years")
这将会显示一个消息,说明它只是一个估计值,因为它没有考虑确切的开始日期和结束日期。
library(tidyverse)
library(lubridate)
today<-mdy(08312015)
dob<-mdy(09071982)
dob %--% today / ddays(365.25)
dob %--% today / ddays(365))
的结果是 33.00274,这是不准确的(应该是32岁,52周和1天)。而 dob %--% today / years(1)
的结果是 32.98082,这是准确的(而且代码更短 :-) )。此外,你的示例中有一个多余的括号。 - Jeff Parker另一个答案,速度更快。请参阅以下速度测试
as.numeric(today - dob) / 365.25
比较所有答案
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
我不确定哪个更正确:32.98082
还是32.98015
。请参见https://dev59.com/s1wY5IYBdhLWcg3ws5kF#32313487
速度测试
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
(今天-生日)/365.25
给出的结果是时间差为32.98015天
而不是年。 - Ignacioas.numeric((today-dob)/365.25)
。如果想要略微提高精度,可以除以365.2425。 - Benjamintoday - dob
不是 lubridate 的正确方法,而是使用基本的 R 功能(difftime
)。请参考我的答案,了解lubridate
的方法。 - Paul Hiemstra