使用具有lubridate函数的mutate计算年龄

HNS*_*SKD 4 r lubridate dplyr

我想根据出生日期计算年龄.

如果我使用lubridate,我会按照R给定出生日期和任意日期的有效和准确的年龄计算(年,月或周)运行以下内容

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

但是,当我尝试使用mutatein 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)
Run Code Online (Sandbox Code Playgroud)

以下工作虽然它给出了所有日期和时间值.即年,月,日,小时,分钟和秒.

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>
Run Code Online (Sandbox Code Playgroud)

以下不起作用:

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

它给出了一个错误:

mutate_impl(.data,dots)出错:无效的下标类型'closure'

我认为可能是因为缺少值.所以,我尝试过:

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

它也给出了一个错误:

mutate_impl(.data,dots)出错:找不到对象'age'

mne*_*nel 5

lubridate,内

  • Period 是一个带有"年"插槽的S4级
  • year是一个S3类对象,具有从句点对象中提取年份槽的方法.

请参阅 https://github.com/hadley/lubridate/blob/master/R/accessors-year.r)提取年份组件的访问器功能.

因此,以下将起作用

df %>% mutate(age = year(as.period(interval(start = birthdate, end = givendate))))
Run Code Online (Sandbox Code Playgroud)


akr*_*run 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
Run Code Online (Sandbox Code Playgroud)

由于类as.period是自带的period,我们可能需要S4方法来提取它

df %>% 
    mutate(age=as.period(interval(start = birthdate, end = givendate))) %>%
   .$age %>%
   .@year %>%
    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
Run Code Online (Sandbox Code Playgroud)

  • 非 dplyr 且更容易理解的版本很简单:`df$age=as.period(interval(start = df$birthdate, end = df$givendate))$year` (9认同)
  • 但如果你因为 hadleyverse 而必须使用 `dplyr`,那么使用 lubridate `year` 函数有什么问题呢?使用“@”访问器被认为是有害的。`df %&gt;% mutate(age=year(as.period(interval(start =birthdate,end=givendate))))` (5认同)