2012-09-07 7 views
26

日付ベクトルに2桁の年がある場合、mdy()は00から68の間を21stセンチュリー年に、69から99を20thセンチュリー年に変換します。たとえば、次のように2桁の年を4桁の年に変換するよりエレガントな方法がありますか?

library(lubridate)  
mdy(c("1/2/54","1/2/68","1/2/69","1/2/99","1/2/04")) 

は、次のような出力が得られます。

Multiple format matches with 5 successes: %m/%d/%y, %m/%d/%Y. 
Using date format %m/%d/%y. 
[1] "2054-01-02 UTC" "2068-01-02 UTC" "1969-01-02 UTC" "1999-01-02 UTC" "2004-01-02 UTC" 

私は1954年から1968年に2054年と2068年を回すために間違った日付から100を減算することにより、事後にこれを修正することができます。しかしそこにありますより洗練されたエラーの少ない2桁の日付の解析方法を使用して、解析処理自体が正しく処理されるようにします。

アップデート:@JoshuaUlrichはstrptimeに私を指摘した後私は私と同様の問題を扱っている、this questionを見つけましたが、基本R.それは次のようになりRの日付の扱いに素晴らしい追加のように思える

を使用して日付解析関数内の2桁の日付に対する世紀選択のカットオフを処理するためのいくつかの方法。ここで

+4

技術的には、日付は正確に解析されています。「入力時に、値00から68までは20と69から99の接頭辞が付きます - それは2004年と2008年のPOSIX標準で指定された動作です)。 '?parse_date'は、形式の'?strptime'を簡単に表示します。 –

+1

私はより正確でなければなりませんでした。私は、 'lubridate'にバグがあることを暗示するつもりはないが、2桁の年月のあいまいさのために、パッケージの自然な振る舞いによって不正確な4桁の年が生じることになる。所望の結果 ")を得ることができる。私は、2桁の日付の所与の範囲に対して所望の世紀を与える「スイッチ」または「カットオフ」値を指定するために、「ルブリッド」内に何らかの方法があることを望んでいました。 – eipi10

+2

lubridateのgithubページに機能リクエストを提出することをお勧めします。 – Spacedman

答えて

22

は、あなたがこれを行うことができる機能です。

library(lubridate) 
x <- mdy(c("1/2/54","1/2/68","1/2/69","1/2/99","1/2/04")) 


foo <- function(x, year=1968){ 
    m <- year(x) %% 100 
    year(x) <- ifelse(m > year %% 100, 1900+m, 2000+m) 
    x 
} 

はそれを試してみてください:

x 
[1] "2054-01-02 UTC" "2068-01-02 UTC" "1969-01-02 UTC" "1999-01-02 UTC" 
[5] "2004-01-02 UTC" 

foo(x) 
[1] "2054-01-02 UTC" "2068-01-02 UTC" "1969-01-02 UTC" "1999-01-02 UTC" 
[5] "2004-01-02 UTC" 

foo(x, 1950) 
[1] "1954-01-02 UTC" "1968-01-02 UTC" "1969-01-02 UTC" "1999-01-02 UTC" 
[5] "2004-01-02 UTC" 

をここに魔法のビットが復帰に剰余演算子%%を使用することです部門の端数部分。したがって、1968 %% 100は、68.

+0

ニース!あなたの答えに気がつきました。ご協力いただきありがとうございます。 – eipi10

2

というまったく同じバグ/機能を経験しました。

エクセル形式の日付(これが最も得意な場所)からRが使用できるものに変換するのに役立つ次の2つの簡単な関数が書かれました。

受け入れられた答えには何も問題はありません。パッケージをあまりにも多くロードしたくないということだけです。

まず、分割して年を交換するためのヘルパー...関数によって使用され

year1900 <- function(dd_y, yrFlip = 50) 
{ 
    dd_y <- as.numeric(dd_y) 
    dd_y[dd_y > yrFlip] <- dd_y[dd_y > yrFlip] + 1900 
    dd_y[dd_y < yrFlip] <- dd_y[dd_y < yrFlip] + 2000 
    return(dd_y) 
} 

その「修正」Excelの日付、種類に応じて:

XLdate <- function(Xd, type = 'b-Y') 
{ 
    switch(type, 
     'b-Y' = as.Date(paste0(substr(Xd, 5, 9), "-", substr(Xd, 1, 3), "-01"), format = "%Y-%b-%d"), 
     'b-y' = as.Date(paste0(year1900(substr(Xd, 5, 6)), "-", substr(Xd, 1, 3), "-01"), 
         format = "%Y-%b-%d"), 
     'Y-b' = as.Date(paste0(substr(Xd, 1, 3), "-", substr(Xd, 5, 9), "-01"), format =  "%Y-%b-%d") 
     ) 
} 

・ホープこれは役に立ちます。

0

別のオプションは、次のようになります。

xxx <- c("01-Jan-54","01-Feb-68","01-Aug-69","01-May-99","01-Jun-04", " 
     31-Dec-68","01-Jan-69", "31-Dec-99") 

解決策はありません。 私は、lubridateがカットオフ日付を指定するオプションを追加したほうがよいと思います。

関連する問題