使用as.Date和grep在一个向量中格式化不一致的日期

时间:2016-11-21 21:12:59

标签: r regex date grep as.date

我对R来说相当新,但是我做了很多挑战,做一些看似简单的任务。

我在一个向量中有许多不一致的记录日期。我的目标是在标有clean_end_date的新矢量中将它们全部转换为相同的R接受日期格式。到目前为止,我已经能够使用as.Dategrep的组合将几乎全部格式化为R中的常规%Y-%m-%d格式:

d$clean_end_date[grep("[0-9]{2}/[0-9]{2}/[0-9]{4}", d$End_Date, value=F)] <- as.character(as.Date(grep("[0-9]{2}/[0-9]{2}/[0-9]{4}", d$End_Date, value=T, fixed = FALSE), format="%d/%m/%Y"))

但是,无论我如何操作代码,都有几个日期无法转换。生成NA的行使用破折号而不是斜杠作为分隔符。不同的日期格式具有相同的字符数,因此计算它们无助于区分它们。我可以手动识别这些行,也可以使用正则表达式字符串匹配函数来识别格式。我认为grep()会有所帮助,但事实并非如此。

我用来格式化大部分代码的代码在这里:

d$clean_end_date <- NA
d$clean_end_date[nchar(as.character(d$End_Date))<10] <- as.character(as.Date(d$End_Date[nchar(as.character(d$End_Date))<10], format="%m/%d/%y"))
d$clean_end_date[grep("[0-9]{4}/[0-9]{2}/[0-9]{2}", d$End_Date, value=F)] <- as.character(as.Date(grep("[0-9]{4}/[0-9]{2}/[0-9]{2}", d$End_Date, value=T, fixed = FALSE), format="%Y/%m/%d"))
d$clean_end_date[grep("[0-9]{4}-[0-9]{2}-[0-9]{2}", d$End_Date, value=F)] <- as.character(as.Date(grep("[0-9]{4}-[0-9]{2}-[0-9]{2}", d$End_Date, value=T, fixed = FALSE), format="%Y-%m-%d"))
d$clean_end_date[grep("[0-9]{2}/[0-9]{2}/[0-9]{4}", d$End_Date, value=F)] <- as.character(as.Date(grep("[0-9]{2}/[0-9]{2}/[0-9]{4}", d$End_Date, value=T, fixed = FALSE), format="%d/%m/%Y"))
d$clean_end_date[d$Community_id==42 & nchar(as.character(d$End_Date))==10] <- as.character(as.Date(d$End_Date[d$Community_id==42 & nchar(as.character(d$End_Date))==10], format="%m/%d/%Y")) 

但是,格式化“11/31/2015”和“2014-02-29”格式的日期有困难。我怀疑这可能是因为R无法区分这种格式和相同长度的格式,如“2015/11/31”和“02-29-2014”。

我真的很感激这方面的帮助。我对R来说相当新,所以特别欣赏一个不能假设我能流利地说R语言的答案。

1 个答案:

答案 0 :(得分:1)

我建议您反思上述guess_format包中提供的lubridate功能。

实施例

在给定一组日期的情况下,从上面链接的官方帮助中引用示例:

x <- c('February 20th 1973',
       "february  14, 2004",
       "Sunday, May 1, 2000",
       "Sunday, May 1, 2000",
       "february  14, 04",
       'Feb 20th 73',
       "January 5 1999 at 7pm")

我们可以通过以下方式申请guess_format

require(lubridate)
as.Date(x = x, format = guess_formats(x, "mdy"))

结果

这将符合某些日期:

>> as.Date(x = x, format = guess_formats(x, "mdy"))
 [1] "1973-02-20" "2004-02-14" "2000-05-01" "2000-05-01" "2004-02-14" "1973-02-20" NA           NA          
 [9] NA           "2000-05-01" NA           NA 

你可以探索guess_format的不同方法,原则上它应该比grep的多个组合产生更简约的代码