【问题标题】:calculating ages in R by subtracting two dates columns通过减去两个日期列来计算 R 中的年龄
【发布时间】:2015-09-09 17:35:54
【问题描述】:

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

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

我尝试使用以下代码(来自类似问题的答案),但在我的情况下不起作用。

求一年的秒数:

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

现在获取您想要的 2 个日期之间的秒数

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

您对浮点数的最终答案将是

years_between_dates <- seconds_between_dates / seconds_in_a_year 

当我尝试将其应用于我的数据框时(注意:使用变量而不是特定日期,所以这可能是原因)我得到了以下信息: seconds_in_a_year

警告信息: 强制引入的 NAs

按照代码,我得到了最终输出:

years_between_dates

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

非常感谢任何帮助!

【问题讨论】:

  • 您说“在您的情况下”它不起作用 - 那么,您的情况是什么?您能否展示您正在使用的数据(例如日期的格式)?例如,发布dput(head(df)) 的结果将创建一个可重复的示例,帮助人们回答

标签: r date


【解决方案1】:

Date 对象中减去另一个Date 对象可以得到以天为单位的时差,例如

> dates = as.Date(c("2007-03-01", "2004-05-23"))
> 
> dates[1] - dates[2]
Time difference of 1012 days

所以,假设一年有 365 天

> age_time_visit = as.numeric(dates[1] - dates[2]) / 365
> age_time_visit
[1] 2.772603

【讨论】:

  • 但是这种方法不会考虑闰日。至少,尝试除以 365.2425。
【解决方案2】:

互联网上散布着各种各样的答案。

我认为我通常使用的那个灵感来自 Ripley 教授: 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

【讨论】:

    【解决方案3】:

    这是一种考虑闰年的方法(不知道以前是否这样做过,但怀疑它有......)。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-06
      • 1970-01-01
      • 1970-01-01
      • 2016-07-14
      • 2021-04-22
      • 2021-06-26
      • 1970-01-01
      相关资源
      最近更新 更多