计算R中的年龄

Bri*_*ian 14 r date

我在R中有两个数据框.一个框架有一个人的出生年份:

YEAR
/1931
/1924
Run Code Online (Sandbox Code Playgroud)

然后另一列显示更近的时间.

RECENT
09/08/2005
11/08/2005
Run Code Online (Sandbox Code Playgroud)

我想做的是减去这些年份,以便我可以计算他们的年龄,但是我不知道如何处理这个问题.有什么帮助吗?

Jim*_*Jim 32

以下函数采用Date对象的向量并计算年龄,正确计算闰年.似乎是比任何其他答案更简单的解决方案.

age = function(from, to) {
  from_lt = as.POSIXlt(from)
  to_lt = as.POSIXlt(to)

  age = to_lt$year - from_lt$year

  ifelse(to_lt$mon < from_lt$mon |
         (to_lt$mon == from_lt$mon & to_lt$mday < from_lt$mday),
         age - 1, age)
}
Run Code Online (Sandbox Code Playgroud)

  • 清晰,快速且仅使用基本功能。还可以正确处理leap年。应该是投票最多的答案。 (3认同)

小智 8

您可以使用lubridate包解决这个问题.

> library(lubridate)
Run Code Online (Sandbox Code Playgroud)

我不认为/ 1931是一个普通的日期类.所以我假设所有条目都是字符串.

> RECENT <- data.frame(recent = c("09/08/2005", "11/08/2005"))
> YEAR <- data.frame(year = c("/1931", "/1924"))
Run Code Online (Sandbox Code Playgroud)

首先,让我们通知R最近的日期是日期.我假设日期是月/日/年订单,所以我使用mdy().如果他们在日/月/年订单中使用dmy().

> RECENT$recent <- mdy(RECENT$recent)
      recent
1 2005-09-08
2 2005-11-08
Run Code Online (Sandbox Code Playgroud)

现在,让我们把年份变成数字,这样我们就可以用它们做一些数学运算.

> YEAR$year <- as.numeric(substr(YEAR$year, 2, 5))
Run Code Online (Sandbox Code Playgroud)

现在就算数学吧.year()提取最近日期的年份值.

> year(RECENT$recent) - YEAR
  year
1   74
2   81
Run Code Online (Sandbox Code Playgroud)

如果您的年份条目实际上是完整日期,您可以获得与年份不同的年份

> YEAR1 <- data.frame(year = mdy("01/08/1931","01/08/1924"))
> as.period(RECENT$recent - YEAR1$year, units = "year")
[1] 74 years and 8 months   81 years and 10 months
Run Code Online (Sandbox Code Playgroud)


Moo*_*per 5

我使用自定义函数,请参见下面的代码,便于在mutate中使用并且非常灵活(您将需要该lubridate软件包)。

例子

get_age("2000-01-01")
# [1] 17
get_age(lubridate::as_date("2000-01-01"))
# [1] 17
get_age("2000-01-01","2015-06-15")
# [1] 15
get_age("2000-01-01",dec = TRUE)
# [1] 17.92175
get_age(c("2000-01-01","2003-04-12"))
# [1] 17 14
get_age(c("2000-01-01","2003-04-12"),dec = TRUE)
# [1] 17.92176 14.64231
Run Code Online (Sandbox Code Playgroud)

功能

#' Get age
#' 
#' Returns age, decimal or not, from single value or vector of strings
#' or dates, compared to a reference date defaulting to now. Note that
#' default is NOT the rounded value of decimal age.
#' @param from_date vector or single value of dates or characters
#' @param to_date date when age is to be computed
#' @param dec return decimal age or not
#' @examples
#' get_age("2000-01-01")
#' get_age(lubridate::as_date("2000-01-01"))
#' get_age("2000-01-01","2015-06-15")
#' get_age("2000-01-01",dec = TRUE)
#' get_age(c("2000-01-01","2003-04-12"))
#' get_age(c("2000-01-01","2003-04-12"),dec = TRUE)
get_age <- function(from_date,to_date = lubridate::now(),dec = FALSE){
  if(is.character(from_date)) from_date <- lubridate::as_date(from_date)
  if(is.character(to_date))   to_date   <- lubridate::as_date(to_date)
  if (dec) { age <- lubridate::interval(start = from_date, end = to_date)/(lubridate::days(365)+lubridate::hours(6))
  } else   { age <- lubridate::year(lubridate::as.period(lubridate::interval(start = from_date, end = to_date)))}
  age
}
Run Code Online (Sandbox Code Playgroud)


Sha*_*ane 2

您可以进行一些格式化:

as.numeric(format(as.Date("01/01/2010", format="%m/%d/%Y"), format="%Y")) - 1930
Run Code Online (Sandbox Code Playgroud)

用你的数据:

> yr <- c(1931, 1924)
> recent <- c("09/08/2005", "11/08/2005")
> as.numeric(format(as.Date(recent, format="%m/%d/%Y"), format="%Y")) - yr
[1] 74 81
Run Code Online (Sandbox Code Playgroud)

由于您的数据位于 data.frame 中(我假设它被称为df),因此它会更像这样:

as.numeric(format(as.Date(df$recent, format="%m/%d/%Y"), format="%Y")) - df$year
Run Code Online (Sandbox Code Playgroud)