Как вычислить разницу дат между двумя записями в R

#r #dplyr

#r #dplyr

Вопрос:

Привет всем, мой df имеет 3 столбца и более 100 строк и выглядит как

 PID  Record_date     DOB
123  25-02-2009  22-08-1944
165  20-04-2017  22-08-1944
  

Я попытался вычислить возраст для PID, но результат был таким

 PID  Record_date     DOB        Age
123  25-02-2009   22-08-1944    65
165  20-04-2017   22-08-1944    73
  

Я рассчитал возраст для PID с помощью приведенного ниже кода

 df$Age <- as.numeric(df$Record_date - df$DOB)/365
df$Age <- round (df$Age, digits = 0)
  

Мой ожидаемый результат и результат

 PID  Record_date        DOB     Age
123  25-02-2009    22-08-1944   64
165  20-04-2017    22-08-1944   72
  

Заранее спасибо

Ответ №1:

Вы можете создать period объект из lubridate пакета и извлечь информацию о годах.

 library(dplyr)
library(lubridate)

df %>%
  mutate(across(c(Record_date, DOB), dmy),
         Age = as.period(DOB %--% Record_date)$year)

#   PID Record_date        DOB Age
# 1 123  2009-02-25 1944-08-22  64
# 2 165  2017-04-20 1944-08-22  72
  

Если вы удалите $year , вы можете получить подробную информацию о периоде:

 #                 Age
# 64y 6m  3d 0H 0M 0S
# 72y 7m 29d 0H 0M 0S
  

Примечание: DOB %--% Record_date это сокращение interval(DOB, Record_date) .

Ответ №2:

дополнительное решение

    library(tidyverse)
   library(lubridate)
    df %>% 
      mutate(across(c(Record_date, DOB), dmy),
             age = (Record_date - DOB) %/% dyears(1))
    
      PID Record_date        DOB age
    1 123  2009-02-25 1944-08-22  64
    2 165  2017-04-20 1944-08-22  72
  

Ответ №3:

Если вы round задаете значения, то полученные вами числа верны. Возможно, вы хотите floor их?

 library(dplyr)
df %>%
  mutate(across(-1, as.Date, '%d-%m-%Y'), 
         age = as.integer(floor((Record_date - DOB)/365)))

#  PID Record_date        DOB age
#1 123  2009-02-25 1944-08-22  64
#2 165  2017-04-20 1944-08-22  72
  

данные

 df <- structure(list(PID = c(123L, 165L), Record_date = c("25-02-2009", 
"20-04-2017"), DOB = c("22-08-1944", "22-08-1944")), 
class = "data.frame", row.names = c(NA, -2L))
  

Комментарии:

1. Это работает, но я сталкиваюсь с незначительными ошибками в разнице дат между одним днем, например, дата записи: 31-12-1993 и DOB: 1927-01-01 я получаю возраст 67 для PID, но ожидаемый результат возраста 66, можете ли вы мне помочь

Ответ №4:

Я использую эту функцию:

 age <- function(dob, age.day = today(), units = "years", floor = TRUE) {
  calc.age = interval(dob, age.day) / duration(num = 1, units = units)
  if (floor) return(as.integer(floor(calc.age)))
  return(calc.age)
}
  

Ответ №5:

Вот базовое решение R.

 diffyear <- function(x, y){
  d <- difftime(x, y)
  z <- as.integer(d)
  years <- as.Date(z, origin = "0000-01-01")
  format(years, "%Y")
}

df1$Record_date <- as.Date(df1$Record_date, "%d-%m-%Y")
df1$DOB <- as.Date(df1$DOB, "%d-%m-%Y")
diffyear(df1[[2]], df1[[3]])
#[1] "64" "72"
  

Теперь присвойте возвращаемое значение новому столбцу.