2017-01-18 6 views
4

Я хотел бы рассчитать возраст, основанный на дате рождения.Расчет возраста с использованием мутата с функциями lubridate

Если я использую lubridate, я бы просто запустить следующий как в Efficient and accurate age calculation (in years, months, or weeks) in R given birth date and an arbitrary date

as.period(new_interval(start = birthdate, end = givendate))$year

Однако, когда я пытался использовать mutate в dplyr создать новую переменную, я столкнулся с ошибкой.

library(dplyr); library(lubridate) 

birthdate <- ymd(c(NA, "1978-12-31", "1979-01-01", "1962-12-30")) 
givendate <- ymd(c(NA, "2015-12-31", "2015-12-31", NA)) 

df <- data.frame(
    birthdate = birthdate, 
    givendate = givendate) 

Следующие действия, хотя и дают все значения даты и времени. т.е. год, месяц, день, час, минута и секунда.

df<-df %>% mutate(age=as.period(interval(start = birthdate, end = givendate))) 

# df 
# birthdate givendate     age 
# 1  <NA>  <NA>     <NA> 
# 2 1978-12-31 2015-12-31 37y 0m 0d 0H 0M 0S 
# 3 1979-01-01 2015-12-31 36y 11m 30d 0H 0M 0S 
# 4 1962-12-30  <NA>     <NA> 

Следующая не работает:

df<-df %>% 
     mutate(age=as.period(interval(start = birthdate, end = givendate))$year) 

Это дает ошибку:

Error in mutate_impl(.data, dots) : invalid subscript type 'closure'

Я думал, что это может быть из-за недостающих значений. Итак, я попробовал:

df<-df %>% 
    mutate(age=as.period(interval(start = birthdate, end = givendate))) %>% 
    mutate(age=if_else(!is.na(age),age$year,age)) 

Это также дает ошибку:

Error in mutate_impl(.data, dots) : object 'age' not found

+0

@akrun Когда я применяю первый 'mutate', я бы уже' age' переменной в наборе данных. Я применяю '$ year' по возрасту, поскольку я думал, что могу извлечь« год »этого периода. – HNSKD

+0

«возраст» имеет класс «период», который может не поддерживаться в 'mutate' – akrun

ответ

1

Мы можем использовать do

df %>% 
    mutate(age=as.period(interval(start = birthdate, end = givendate))) %>% 
    do(data.frame(.[setdiff(names(.), "age")], 
     age = ifelse(!is.na(.$age), .$age$year, .$age))) 
# birthdate givendate age 
#1  <NA>  <NA> NA 
#2 1978-12-31 2015-12-31 37 
#3 1979-01-01 2015-12-31 36 
#4 1962-12-30  <NA> NA 

Как as.period приходит с period класса, мы, возможно, потребуется S4 для его извлечения

df %>% 
    mutate(age=as.period(interval(start = birthdate, end = givendate))) %>% 
    .$age %>% 
    [email protected] %>% 
    mutate(df, age = .) 
# birthdate givendate age 
#1  <NA>  <NA> NA 
#2 1978-12-31 2015-12-31 37 
#3 1979-01-01 2015-12-31 36 
#4 1962-12-30  <NA> NA 
+0

Этот код короткий и сладкий, но как я могу это понять? – HNSKD

+0

@HNSKD Черт, я также добавил версию с 'mutate' – akrun

+8

Не-dplyr и гораздо более понятная версия просто:' df $ age = as.период (интервал (start = df $ birthdate, end = df $ givendate)) $ year' – Spacedman

2

Мы можем использовать функцию year от lubridate, чтобы получить разницу между двумя датами в годах.

library(dplyr); library(lubridate) 
df %>% mutate(age = year(givendate) - year(birthdate)) 

# birthdate givendate age 
#1  <NA>  <NA> NA 
#2 1978-12-31 2015-12-31 37 
#3 1979-01-01 2015-12-31 36 
#4 1962-12-30  <NA> NA 
+3

Я не думаю, что использование одного года точно для вычисления возраста. Если дата рождения человека - 1978-12-31, и данная дата - 2015-12-30, ему все равно будет 36 лет, так как его день рождения еще не прошел. – HNSKD

+1

@HNSKD ohh..yes! Потому что 'year' извлекает только часть года Date. Наиболее простой подход был бы предложен предложенным @Spacedman 'as.period (interval (start = df $ birthdate, end = df $ givendate)) $ year' –

5

В lubridate,

  • Period является классом S4, с прорезью «год»
  • год является классом объекта S3, с помощью способа, чтобы извлечь год слот от объекта периода.

см. https://github.com/hadley/lubridate/blob/master/R/accessors-year.r) функция доступа для извлечения компонента года.

Таким образом, следующие будут работать

df %>% mutate(age = year(as.period(interval(start = birthdate, end = givendate)))) 

 Смежные вопросы

  • Нет связанных вопросов^_^