对日期使用 mutate 给出数值

Using mutate with dates gives numerical values

我正在使用 lubridatedplyr 包分别处理日期变量和创建新的日期变量。

library(lubridate)
library(dplyr)

df 成为我的数据框。我有两个变量 date1date2。我想创建一个新变量 date,使其采用 date1 的值。如果缺少 date1,则取而代之的是 date2 的值。

df <- data.frame(date1 = c("24/01/2016",NA,"22/07/2016"),
                 date2 = c("31/01/2016","09/02/2017",NA),
                 stringsAsFactors=FALSE)`

以上命令给出:

       date1      date2
1 24/01/2016 31/01/2016
2       <NA> 09/02/2017
3 22/07/2016       <NA>

我尝试了以下我认为可以给我所需结果的方法。但是,新的 date 变量是数字。

df %>% 
   mutate_at(vars(date1,date2),dmy) %>% 
   mutate(date=ifelse(is.na(date1),date2,date1))

       date1      date2  date
1 2016-01-24 2016-01-31 16824
2       <NA> 2017-02-09 17206
3 2016-07-22       <NA> 17004

我要:

       date1      date2       date
1 2016-01-24 2016-01-31 2016-01-24
2       <NA> 2017-02-09 2017-02-09
3 2016-07-22       <NA> 2016-07-22

如何解决这个问题?

使用 dplyr::if_else 而不是 base::ifelse,根据 ?if_else,后者类型更安全,

Compared to the base ifelse(), this function is more strict. It checks that true and false are the same type. This strictness makes the output type more predictable, and makes it somewhat faster.

df %>% 
      mutate_at(vars(date1,date2),dmy) %>% 
      mutate(date=if_else(is.na(date1),date2,date1))

#       date1      date2       date
#1 2016-01-24 2016-01-31 2016-01-24
#2       <NA> 2017-02-09 2017-02-09
#3 2016-07-22       <NA> 2016-07-22

另一种选择是使用 coalesce,如果不是 NA,它从 date1 中获取值,否则从 date2:

中获取值
df %>% 
      mutate_at(vars(date1,date2),dmy) %>% 
      mutate(date = coalesce(date1, date2))

#       date1      date2       date
#1 2016-01-24 2016-01-31 2016-01-24
#2       <NA> 2017-02-09 2017-02-09
#3 2016-07-22       <NA> 2016-07-22

如果您想保留原始代码,只需将 as.Date 包裹在 ifelse 周围,因为 ifelse 剥离了结果的 class,只保留底层数据即自 1970 年 1 月 1 日以来的天数:

df %>% 
      mutate_at(vars(date1,date2),dmy) %>% 
      mutate(date=as.Date(ifelse(is.na(date1),date2,date1), origin = "1970-01-01"))