到目前为止我所拥有的是一个数据帧列,其中包含不同字符格式的日期。有些出现在%d.%m.%Y
模式中,有些出现在%m/%d/%Y
中:
data$initialDiagnose = as.character(data$initialDiagnose)
data$initialDiagnose[1:10]
[1] "14.01.2009" "9/22/2005" "4/21/2010" "28.01.2010" "09.01.2009" "3/28/2005" "04.01.2005" "04.01.2005" "9/17/2010" "03.01.2010"
我希望它们以一种格式作为Date(),但R当然拒绝。 所以我首先尝试通过分隔符更改它们:
data$initialDiagnose[grep('/', data$initialDiagnose)] = as.character.Date(data$initialDiagnose[grep('/', data$initialDiagnose)], format = '%m/%d/%Y')
类似于'。'日期。但它没有用。
如何将它们全部更改为一种格式,我可以使用它们?
a <- as.Date(data$initialDiagnose,format="%m/%d/%Y") # Produces NA when format is not "%m/%d/%Y"
b <- as.Date(data$initialDiagnose,format="%d.%m.%Y") # Produces NA when format is not "%d.%m.%Y"
a[is.na(a)] <- b[!is.na(b)] # Combine both while keeping their ranks
data$initialDiagnose <- a # Put it back in your dataframe
data$initialDiagnose
[1] "2009-01-14" "2005-09-22" "2010-04-21" "2010-01-28" "2009-01-09" "2005-03-28" "2005-01-04" "2005-01-04" "2010-09-17" "2010-01-03"
另外,这里的上述方法适用于您有三种(或更多种)不同格式的情况:
data$initialDiagnose
[1] 14.01.2009 9/22/2005 12 Mar 97 4/21/2010 28.01.2010 09.01.2009 3/28/2005
Levels: 09.01.2009 12 Mar 97 14.01.2009 28.01.2010 3/28/2005 4/21/2010 9/22/2005
multidate <- function(data, formats){
a<-list()
for(i in 1:length(formats)){
a[[i]]<- as.Date(data,format=formats[i])
a[[1]][!is.na(a[[i]])]<-a[[i]][!is.na(a[[i]])]
}
a[[1]]
}
data$initialDiagnose <- multidate(data$initialDiagnose,
c("%m/%d/%Y","%d.%m.%Y","%d %b %y"))
data$initialDiagnose
[1] "2009-01-14" "2005-09-22" "1997-03-12" "2010-04-21" "2010-01-28" "2009-01-09" "2005-03-28"
我喜欢lubridate的易用性:
library(lubridate)
# note added ugly formats below
data <- data.frame(initialDiagnose = c("14.01.2009", "9/22/2005",
"4/21/2010", "28.01.2010", "09.01.2009", "3/28/2005",
"04.01.2005", "04.01.2005", "Created on 9/17/2010", "03 01 2010"))
mdy <- mdy(data$initialDiagnose)
dmy <- dmy(data$initialDiagnose)
mdy[is.na(mdy)] <- dmy[is.na(mdy)] # some dates are ambiguous, here we give
data$initialDiagnose <- mdy # mdy precedence over dmy
data
# initialDiagnose
# 2009-01-14
# 2005-09-22
# 2010-04-21
# 2010-01-28
# 2009-09-01
# 2005-03-28
# 2005-04-01
# 2005-04-01
# 2010-09-17
# 2010-03-01
自2012年MattBagg's answer以来,lubridate
添加了parse_date_time
函数,该函数专为这种情况而设计,可以在一行中解决这个问题:
library(lubridate)
data <- data.frame(initialDiagnose = c("14.01.2009", "9/22/2005",
"4/21/2010", "28.01.2010", "09.01.2009", "3/28/2005",
"04.01.2005", "04.01.2005", "Created on 9/17/2010", "03 01 2010"))
parse_date_time(data$initialDiagnose, orders = c('mdy', 'dmy'))
[1] "2009-01-14 UTC" "2005-09-22 UTC" "2010-04-21 UTC" "2010-01-28 UTC" "2009-01-09 UTC"
[6] "2005-03-28 UTC" "2005-01-04 UTC" "2005-01-04 UTC" "2010-09-17 UTC" "2010-03-01 UTC"
orders=
参数是一个字符向量,按照应测试的顺序包含可能的日期时间解析格式。因此,通过给c('mdy', 'dmy')
,lubridate将尝试将所有字符串解析为Month, Date, Year
格式。如果它不能成功完成(例如,日期14.01.2009
将无法工作,因为没有第14个月),它将尝试列表中的下一个,直到解析所有字符串,或者所有订单都用尽。