10

このようなさまざまな形式の日付を持つ文字ベクトルがあります

dates <- c("23/11/12", "20/10/2012", "22/10/2012" ,"23/11/12")

これらを日付に変換したい。lubridate パッケージの非常に優れた dmy を試しましたが、うまくいきません:

    dmy(dates)
[1] "0012-11-23 UTC" "2012-10-20 UTC" "2012-10-22 UTC" "0012-11-23 UTC"

/12 年を 0012 として扱っています。

そのため、正規表現を使用して各タイプを選択し、as.Date() を使用して個別に日付に変換しようとしています。ただし、dd/mm/yy のみを選択しようとした正規表現は機能しません。

dates[grep('[0-9]{2}/[0-9]{2}/[0-9]{2,2}', dates)]

戻り値

[1] "23/11/12"   "20/10/2012" "22/10/2012" "23/11/12"

{2,2} は、すべてではなく、正確に 2 つの数値を取得する必要があると考えました。私は正規表現があまり得意ではないので、助けていただければ幸いです。

ありがとう

編集

私が実際に持っているのは、以下の3つの異なるタイプの日付です

dates <- c("23-Jul-2013", "23/11/12", "20/10/2012", "22/10/2012" ,"23/11/12")

そして、これらを日付に変換したい

parse_date_time(dates,c('dmy'))

私にくれます

[1] "2013-07-23" "0012-11-23" "2012-10-20" "2012-10-22" "0012-11-23"

しかし、これは間違っており、0012 は 2012 である必要があります。これに対する (かなり単純な) 解決策が必要です。

私が現在持っている1つの解決策(@plannapusのおかげ)は、正規表現を使用することです

    asDateRegex <- function(dates, 
        #selects strings from the vector dates using regexes and converts these to Dates
        regexes = c('[0-9]{2}/[0-9]{2}/[0-9]{4}', #dd/mm/yyyy
            '[0-9]{2}/[0-9]{2}/[0-9]{2}$', #dd/mm/yy
            '[0-9]{2}-[[:alpha:]]{3}-[0-9]{4}'), #dd-mon-yyyy
        orders = 'dmy',
        ...){
        require(lubridate)
        new_dates <- as.Date(rep(NA, length(dates)))
        for(reg in regexes){
            new_dates[grep(reg, dates)] <- as.Date(parse_date_time(dates[grep(reg, dates)], order = orders))
        }
        new_dates
    }

asDateRegex (dates)
[1] "2012-10-20" "2013-07-23" "2012-11-23" "2012-10-22" "2012-11-23"

しかし、これはあまりエレガントではありません。より良い解決策はありますか?

4

6 に答える 6

15

parse_date_time次から使用できます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"

ただし、フォーマットの順序が重要であることに注意してください。

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"

編集

内部的parse_date_timeに使用してguess_formatsいます(これはいくつかの正規表現を使用していると思います):

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

parse_date_timeコメントで述べたように、次のように使用できます。

as.Date(dates, format = guess_formats(dates,c('dmy')))
于 2013-10-17T11:22:05.813 に答える
7

日付の入力長に基づいて形式を選択できます。

y <- ifelse(nchar(dates) == 8, "y", "Y")
as.Date(dates, format = paste0("%d/%m/%", y))
于 2013-10-17T12:14:21.817 に答える
1

regexベースのソリューションでの最初の試みに続いて、gsubthis を使用してregexpから、希望する日時形式に変換してみてください...

#  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"
于 2013-10-17T11:26:33.600 に答える
1

これは、受け入れられていない回答で(まだ)対処されていない、より一般的なケースの基本的なRの方法です。

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"
于 2013-10-17T13:21:14.460 に答える