如何使用 dplyr 和 r 中的辅助函数强制数据框中变量的日期类型?
How to coerce date type for variables in dataframe using dplyr and a helper function in r?
我有一个包含 50 个变量的数据框。为简单起见,我创建了一个包含 5 个变量的数据框。我希望将位置 2:5 中的变量强制转换为日期变量而不是字符变量。
ID<-1:3
ASSISTANCEPERIODFROM<-c("14/06/2009", "13/01/2010","13/01/2010")
ASSISTANCEPERIODTO<-c("14/06/2009","30/06/2010","30/06/2010")
APPROVEDDATE<-c("14/11/2009","30/12/2010","30/01/2011")
DATEOFBIRTH<-c("14/11/1990","30/12/1970","30/01/2000")
df<-data.frame(ID,ASSISTANCEPERIODFROM,ASSISTANCEPERIODTO,APPROVEDDATE,DATEOFBIRTH,stringsAsFactors=FALSE)
我尝试了 dplyr 中的 mutate_each
函数以及辅助函数 contains
,但是当我尝试两个字符串时,我无法得到我想要的结果。这两个字符串是 PERIOD
和 DATE
。以下是我的方法。
library(dplyr)
library(stringr)
library(lubridate)
df<-df %>%
mutate_each(funs(dmy(.)),contains(c("PERIOD","DATE")))
# Error: is.string(match) is not TRUE
df<-df %>%
mutate_each(funs(dmy(.)),contains("PERIOD"|"DATE"))
# Error in "PERIOD" | "DATE" :
# operations are possible only for numeric, logical or complex types
df<-df %>%
mutate_each(funs(dmy(.)),contains("PERIOD|DATE"))
# No error but doesn not give me what I want
df<-df %>%
mutate_each(funs(dmy(.)),as.numeric(str_detect(colnames(df),"PERIOD|DATE")))
我也在str_detect
试过运气,但也不行。
contains
不处理 regex
,因此它不会检测到任何包含 PERIOD|DATE
的列。尝试:
df %>% mutate_each(funs(dmy(.)),union(contains("PERIOD"),contains("DATE")))
# ID ASSISTANCEPERIODFROM ASSISTANCEPERIODTO APPROVEDDATE DATEOFBIRTH
#1 1 2009-06-14 2009-06-14 2009-11-14 1990-11-14
#2 2 2010-01-13 2010-06-30 2010-12-30 1970-12-30
#3 3 2010-01-13 2010-06-30 2011-01-30 2000-01-30
否则,只需使用matches
:
df %>% mutate_each(funs(dmy(.)),matches("PERIOD|DATE"))
得到相同的结果。
回答你的问题:
df[2:5] <- lapply(df[2:5], as.Date, "%d/%m/%Y")
不需要dplyr
但是看看你想做什么,你似乎只想转换名称中有 "DATE" 或 "PERIOD" 的变量 ?
注意几点:
- 使用
mutate_at
而不是 mutate_each
因为后者已被弃用。
- 使用
matches
而不是 contains
并按照 dplyr
最新版本的要求将整个内容包装在 vars
中
- 使用
as.Date
(character
输入的方法)和 format
参数来解析日期
所有这些导致:
library(dplyr)
library(stringr)
library(lubridate)
df_foo = data_frame(
ID = 1:3,
ASSISTANCEPERIODFROM = c("14/06/2009", "13/01/2010","13/01/2010"),
ASSISTANCEPERIODTO = c("14/06/2009","30/06/2010","30/06/2010"),
APPROVEDDATE = c("14/11/2009","30/12/2010","30/01/2011"),
DATEOFBIRTH = c("14/11/1990","30/12/1970","30/01/2000")
)
df_foo %>%
dplyr::mutate_at(
.cols = vars(dplyr::matches("(PERIOD)|(DATE)")),
funs(
as.Date.character(., format = "%d/%m/%Y")
)
)
# A tibble: 3 × 5
ID ASSISTANCEPERIODFROM ASSISTANCEPERIODTO APPROVEDDATE DATEOFBIRTH
<int> <date> <date> <date> <date>
1 1 2009-06-14 2009-06-14 2009-11-14 1990-11-14
2 2 2010-01-13 2010-06-30 2010-12-30 1970-12-30
3 3 2010-01-13 2010-06-30 2011-01-30 2000-01-30
我有一个包含 50 个变量的数据框。为简单起见,我创建了一个包含 5 个变量的数据框。我希望将位置 2:5 中的变量强制转换为日期变量而不是字符变量。
ID<-1:3
ASSISTANCEPERIODFROM<-c("14/06/2009", "13/01/2010","13/01/2010")
ASSISTANCEPERIODTO<-c("14/06/2009","30/06/2010","30/06/2010")
APPROVEDDATE<-c("14/11/2009","30/12/2010","30/01/2011")
DATEOFBIRTH<-c("14/11/1990","30/12/1970","30/01/2000")
df<-data.frame(ID,ASSISTANCEPERIODFROM,ASSISTANCEPERIODTO,APPROVEDDATE,DATEOFBIRTH,stringsAsFactors=FALSE)
我尝试了 dplyr 中的 mutate_each
函数以及辅助函数 contains
,但是当我尝试两个字符串时,我无法得到我想要的结果。这两个字符串是 PERIOD
和 DATE
。以下是我的方法。
library(dplyr)
library(stringr)
library(lubridate)
df<-df %>%
mutate_each(funs(dmy(.)),contains(c("PERIOD","DATE")))
# Error: is.string(match) is not TRUE
df<-df %>%
mutate_each(funs(dmy(.)),contains("PERIOD"|"DATE"))
# Error in "PERIOD" | "DATE" :
# operations are possible only for numeric, logical or complex types
df<-df %>%
mutate_each(funs(dmy(.)),contains("PERIOD|DATE"))
# No error but doesn not give me what I want
df<-df %>%
mutate_each(funs(dmy(.)),as.numeric(str_detect(colnames(df),"PERIOD|DATE")))
我也在str_detect
试过运气,但也不行。
contains
不处理 regex
,因此它不会检测到任何包含 PERIOD|DATE
的列。尝试:
df %>% mutate_each(funs(dmy(.)),union(contains("PERIOD"),contains("DATE")))
# ID ASSISTANCEPERIODFROM ASSISTANCEPERIODTO APPROVEDDATE DATEOFBIRTH
#1 1 2009-06-14 2009-06-14 2009-11-14 1990-11-14
#2 2 2010-01-13 2010-06-30 2010-12-30 1970-12-30
#3 3 2010-01-13 2010-06-30 2011-01-30 2000-01-30
否则,只需使用matches
:
df %>% mutate_each(funs(dmy(.)),matches("PERIOD|DATE"))
得到相同的结果。
回答你的问题:
df[2:5] <- lapply(df[2:5], as.Date, "%d/%m/%Y")
不需要dplyr
但是看看你想做什么,你似乎只想转换名称中有 "DATE" 或 "PERIOD" 的变量 ?
注意几点:
- 使用
mutate_at
而不是mutate_each
因为后者已被弃用。 - 使用
matches
而不是contains
并按照dplyr
最新版本的要求将整个内容包装在 - 使用
as.Date
(character
输入的方法)和format
参数来解析日期
vars
中
所有这些导致:
library(dplyr)
library(stringr)
library(lubridate)
df_foo = data_frame(
ID = 1:3,
ASSISTANCEPERIODFROM = c("14/06/2009", "13/01/2010","13/01/2010"),
ASSISTANCEPERIODTO = c("14/06/2009","30/06/2010","30/06/2010"),
APPROVEDDATE = c("14/11/2009","30/12/2010","30/01/2011"),
DATEOFBIRTH = c("14/11/1990","30/12/1970","30/01/2000")
)
df_foo %>%
dplyr::mutate_at(
.cols = vars(dplyr::matches("(PERIOD)|(DATE)")),
funs(
as.Date.character(., format = "%d/%m/%Y")
)
)
# A tibble: 3 × 5
ID ASSISTANCEPERIODFROM ASSISTANCEPERIODTO APPROVEDDATE DATEOFBIRTH
<int> <date> <date> <date> <date>
1 1 2009-06-14 2009-06-14 2009-11-14 1990-11-14
2 2 2010-01-13 2010-06-30 2010-12-30 1970-12-30
3 3 2010-01-13 2010-06-30 2011-01-30 2000-01-30