Convert dd/mm/yy and dd/mm/yyyy to Dates

后端 未结 6 1311
挽巷
挽巷 2020-11-28 15:39

I have some a character vector with dates in various formats like this

dates <- c(\"23/11/12\", \"20/10/2012\", \"22/10/2012\" ,\"23/11/12\")
相关标签:
6条回答
  • 2020-11-28 16:16

    You can choose the format based upon input length of date.

    y <- ifelse(nchar(dates) == 8, "y", "Y")
    as.Date(dates, format = paste0("%d/%m/%", y))
    
    0 讨论(0)
  • 2020-11-28 16:17

    You can use strsplit and nchar to get a subvector of dates where the year is two characters long:

    > dates[sapply(strsplit(dates,"/"),function(x)nchar(x)[3]==2)]
    [1] "23/11/12" "23/11/12"
    
    0 讨论(0)
  • 2020-11-28 16:21

    You can use parse_date_time from lubridate:

    some.dates <- c("23/11/12", "20/10/2012", "22/10/2012" ,"23/11/12")
    parse_date_time(some.dates,c('dmy'))
    [1] "2012-11-23 UTC" "2012-10-20 UTC" "2012-10-22 UTC" "2012-11-23 UTC"
    

    But , Note that the order of format is important :

    some.dates <- c("20/10/2012","23/11/12",  "22/10/2012" ,"23/11/12")
    parse_date_time(some.dates,c('dmY','dmy'))
    
    [1] "2012-10-20 UTC" "2012-11-23 UTC" "2012-10-22 UTC" "2012-11-23 UTC"
    

    EDIT

    Internally parse_date_time is using guess_formats (which I guess uses some regular expressions):

    guess_formats(some.dates,c('dmy'))
           dmy        dmy        dmy        dmy 
    "%d/%m/%Y" "%d/%m/%y" "%d/%m/%Y" "%d/%m/%y" 
    

    As mentioned in the comment you can use parse_date_time like this:

    as.Date(dates, format = guess_formats(dates,c('dmy')))
    
    0 讨论(0)
  • 2020-11-28 16:26

    If you really wanted to do it in regexp you should have used $ to signify that there was nothing (i.e. end of string) after the last two-digits numbers:

    dates[grep('[0-9]{2}/[0-9]{2}/[0-9]{2}$', dates)]
    [1] "23/11/12" "23/11/12"
    

    Otherwise, in addition to the other answers you can have a look here and here for other ways of handling multiple date formats.

    0 讨论(0)
  • 2020-11-28 16:31

    Following your original attempt at regex based solutions, you may try gsub using this regexp, then converting to any date-time format you wish...

    #  Replace 4 digit years with two digit years
    short <- gsub( "([0-9]{2})([0-9]{2})$" , "\\2" , dates )
    #[1] "23/11/12" "20/10/12" "22/10/12" "23/11/12"
    
    
    as.Date( short , format = "%d/%m/%y" )
    #[1] "2012-11-23" "2012-10-20" "2012-10-22" "2012-11-23"
    
    0 讨论(0)
  • 2020-11-28 16:42

    Here's a base R way for the more general case not (yet) addressed in the unaccepted answers.

    dates <- c("23-Jul-2013", "23/11/12", "20/10/2012", "22/10/2012" ,"23/11/12")
    fmts <- list('%d-%b-%Y', '%d/%m/%y', '%d/%m/%Y')
    d <- mapply(as.Date, list(dates), fmts, SIMPLIFY=FALSE)
    max.d <- do.call(function(...) pmax(..., na.rm=TRUE), d)
    min.d <- do.call(function(...) pmin(..., na.rm=TRUE), d)
    max.d[max.d > Sys.Date()] <- min.d[max.d > Sys.Date()]
    max.d
    # [1] "2012-11-23" "2012-10-20" "2012-10-22" "2012-11-23"
    
    0 讨论(0)
提交回复
热议问题