【问题标题】:Using as.Date and grep to format inconsistent dates in one vector使用 as.Date 和 grep 在一个向量中格式化不一致的日期
【发布时间】:2017-04-05 09:33:42
【问题描述】:

我对 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")) 

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

非常感谢您对此的帮助。我对 R 相当陌生,所以特别感谢一个不假设我能流利地说 R 语言的答案。

【问题讨论】:

标签: r regex date as.date


【解决方案1】:

我建议考虑上述lubridate 包中的guess_format 函数。

示例

引用上面链接的官方帮助中的示例,给出一组日期:

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 的多个组合产生更简洁的代码

【讨论】:

    猜你喜欢
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    相关资源
    最近更新 更多