对日期使用 mutate 给出数值
Using mutate with dates gives numerical values
我正在使用 lubridate
和 dplyr
包分别处理日期变量和创建新的日期变量。
library(lubridate)
library(dplyr)
让 df
成为我的数据框。我有两个变量 date1
和 date2
。我想创建一个新变量 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"))
我正在使用 lubridate
和 dplyr
包分别处理日期变量和创建新的日期变量。
library(lubridate)
library(dplyr)
让 df
成为我的数据框。我有两个变量 date1
和 date2
。我想创建一个新变量 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"))