使用带有日期的mutate可以得到数值

时间:2017-01-16 02:55:02

标签: r date dplyr lubridate

我正在使用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

如何解决这个问题?

1 个答案:

答案 0 :(得分:7)

使用dplyr::if_else代替base::ifelse,根据?if_else,类型更安全,

  

与基础ifelse()相比,此函数更严格。它检查   真假都属于同一类型。这种严格使得   输出类型更可预测,并使其更快。

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,如果不是date1,则会从NA获取值,否则从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剥离了结果类,只保留基础数据,即自1970-01-01以来的天数

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