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

HNS*_*SKD 2 r date lubridate dplyr

我使用lubridatedplyr包来处理日期变量并分别创建一个新的日期变量.

library(lubridate)
library(dplyr)
Run Code Online (Sandbox Code Playgroud)

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

上面的命令给出:

       date1      date2
1 24/01/2016 31/01/2016
2       <NA> 09/02/2017
3 22/07/2016       <NA>
Run Code Online (Sandbox Code Playgroud)

我尝试了以下,我认为可以给我所需的结果.但是,新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
Run Code Online (Sandbox Code Playgroud)

我想要:

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

我该如何解决这个问题?

Psi*_*dom 9

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

与基础ifelse()相比,此函数更严格.它检查true和false是否为同一类型.这种严格性使输出类型更具可预测性,并使其更快.

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

另一种选择是使用coalesce,date1如果不是NAdate2以下值获取值,则取值:

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

如果你想保持你的原代码,只是包装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"))
Run Code Online (Sandbox Code Playgroud)