将包含不同日期格式的数据框列转换为Date对象

时间:2016-02-18 09:45:39

标签: regex r date

我有一个类character的数据框列,其中包含不同的日期格式:

foo=data.frame(Date=c("29-Jan-16","29-Jan-16","2/5/2016","2/5/2016"),stringsAsFactors = F)

我想将列Date转换为类Date对象的向量。我可以单独正确地解析每种格式:

> as.Date( foo$Date, format = "%d-%b-%y" )
[1] "2016-01-29" "2016-01-29" NA           NA          
> as.Date( foo$Date, format = "%m/%d/%Y" )
[1] NA           NA           "2016-02-05" "2016-02-05"

所以我想加入ifelsegrepl的两个解析说明。请注意grepl正确识别使用第一种格式的行

> grepl("-",foo$Date)
[1]  TRUE  TRUE FALSE FALSE

然而,complet指令不起作用:

bar = foo
bar$Date=ifelse(grepl("-",foo$Date),
                      as.Date( foo$Date, format = "%d-%b-%y" ),
                      as.Date( foo$Date, format = "%m/%d/%Y" ))

> bar
   Date
1 16829
2 16829
3 16836
4 16836

问题:

  1. 你能帮我理解发生了什么吗?
  2. 即使我设法在你的帮助下修复我的解决方案,我也会了解更多有关R的知识,但这个解决方案仍然不是最理想的。原因是"辉煌"填充数据框的人可能会选择使用更多日期格式(之前已经发生过,并且可能会再次发生)。然后我将需要嵌套更多ifelse,并创建更复杂的regexp。代码将很快变得令人讨厌且难以理解。是不是有办法让R自动为foo$Date的每个元素找到正确的数据格式?

1 个答案:

答案 0 :(得分:3)

使用lubridate会更容易。假设“日期”的格式是日,月,年的顺序,我们可以使用dmy

library(lubridate)
dmy(foo$Date)
#[1] "2016-01-29 UTC" "2016-01-29 UTC" "2016-05-02 UTC" "2016-05-02 UTC"

如果订单中还有其他变体,我们也可以将guess_formatsparse_date_time一起使用。

 with(foo, parse_date_time(Date, 
         orders=guess_formats(Date, c('dby', 'mdy'))))
 #[1] "2016-01-29 UTC" "2016-01-29 UTC" "2016-02-05 UTC" "2016-02-05 UTC"

关于在OP代码中使用ifelse,我们在numeric类中得到的输出可以转换回Date

v1 <- ifelse(grepl("-",foo$Date),
                  as.Date( foo$Date, format = "%d-%b-%y" ),
                  as.Date( foo$Date, format = "%m/%d/%Y" ))

as.Date(v1, origin='1970-01-01')
#[1] "2016-01-29" "2016-01-29" "2016-02-05" "2016-02-05"