通过减去两个日期列来计算R中的年龄

时间:2015-09-09 17:35:54

标签: r date

我有2列,其中约有2000行日期。一个是访问日期(df $ visitdate)的变量,另一个是个人的出生日期(df $ birthday)。

想知道是否有任何简单的方法可以减去访问日期 - 出生日期以创建变量"访问时的年龄",计算闰年等。

我尝试使用以下代码(来自类似问题的答案),但它在我的案例中没有用。

查找一年内的秒数:

seconds_in_a_year <- as.integer((seconds(ymd("2010-01-01")) - seconds(ymd("2009-01-01"))))

现在获得您希望的两个日期之间的秒数

seconds_between_dates <- as.integer(seconds(date1) - seconds(date2))

浮点数的最终答案将是

years_between_dates <- seconds_between_dates / seconds_in_a_year 

当我尝试将此应用到我的数据框时(注意:使用变量而不是特定日期,所以这可能是原因)我得到以下内容:   seconds_in_a_year&lt; - as.integer((秒(ymd(df $ visitdate)) - 秒(ymd(df $ birthday))))

警告讯息: 强制引入的NA

遵循代码,我得到了最终输出:

years_between_dates

[1] 1.157407e-05 [2] 1.157407e-05

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

这有散布在互联网上的各种答案。

我认为我通常使用的那个灵感来自里普利教授: http://r.789695.n4.nabble.com/Calculate-difference-between-dates-in-years-td835196.html

age_years <- function(first, second) 
{ 
lt <- data.frame(first, second) 
age <- as.numeric(format(lt[,2],format="%Y")) - as.numeric(format(lt[,1],format="%Y")) 
first <- as.Date(paste(format(lt[,2],format="%Y"),"-",format(lt[,1],format="%m-%d"),sep="")) 
age[which(first > lt[,2])] <- age[which(first > lt[,2])] - 1 
age 
}

https://gist.github.com/mmparker/7254445

还有另一种方法

或者你只想要原始的十进制年数,你可以得到天数除以365.2425

答案 1 :(得分:0)

这是一种解释闰年的方法(不知道以前是否已经完成,但怀疑它已经......)。

get.age <- function(from, to) {
  require(lubridate)    # for leap_year(...)
  n   <- as.integer(to-from)
  n.l <- sum(leap_year(seq(from,to,by=1)))
  n.l/366 + (n+1-n.l)/365
}
get.age(as.Date("2009-01-01"),as.Date("2012-12-31"))  
# [1] 4 
get.age(as.Date("2012-01-01"),as.Date("2012-01-31"))   # 2012 was a leap year
# [1] 0.08469945
get.age(as.Date("2011-01-01"),as.Date("2011-01-31"))   # 2011 was not
# [1] 0.08493151

所以基本的想法是在fromto(包括)之间的每一天创建一个包含一个元素的向量,然后在每一天说明当天是否是闰年的一部分或不。我们将闰年和非闰年分别加起来计算年数:

leap-year-days/366 + non-leap-year-days/365

这适用于单个日期(长度为1的向量)。要按照您的要求为日期列启用此功能,我们会使用Vectorize(...)

vget.age <- Vectorize(get.age)   # vectorized version

然后演示:

# example data set
set.seed(1)    # for reproducible example
today <- as.Date("2015-09-09")
df <- data.frame(birth.date=today-sample(1000:10000,2000)) # 2000 birthdays
result <- vget.age(df$birth.date,today)                    # how old are they?
head(result)
# [1]  9.282192 11.909589 16.854795 25.115068  7.706849 24.865753