Rで文字列から日付に変換するための「標準の明確な日付」形式は何ですか?


94

以下をご検討ください

$ R --vanilla

> as.Date("01 Jan 2000")
Error in charToDate(x) :
    character string is not in a standard unambiguous format

しかし、その日は明らかにされ、標準の明確な形式で。エラーメッセージはなぜですか?

さらに悪いことに、あいまいな日付は警告やエラーなしで受け入れられ、誤って読み取られてしまいます。

> as.Date("01/01/2000")
[1] "0001-01-20"

このエラーメッセージが含まれている[R]タグで28個の質問を検索しました。iiuc形式の指定に関連するソリューションと回避策のすべて。この質問は、とにかく標準の明確なフォーマットをどこに定義しているのかを尋ねている点が異なり、変更できますか?誰もがこれらのメッセージを受け取りますか、それとも私だけですか?おそらくそれはロケールに関連していますか?

言い換えれば、フォーマットを指定する必要があるよりも良い解決策はありますか?

「[R]標準のあいまいでない形式」を含む29の質問

> sessionInfo()
R version 2.15.2 (2012-10-26)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_United Kingdom.1252
[2] LC_CTYPE=English_United Kingdom.1252
[3] LC_MONETARY=English_United Kingdom.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United Kingdom.1252

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

13
as.Date.character入力の関数定義による判断は、次の2つの形式についてのみテストされます:"%Y-%m-%d"および"%Y/%m/%d"。それらのいずれかに一致する場合は、「あいまいでない」と見なされます。
plannapus 2013

7
@CarlWitthoft「私も読んだか」は、答えが盲目的に明白であることを暗示しているよう?as.Dateです。これはどこで役立ちますか?
Matt Dowle 2013

2
間違いなく「1949年1月24日」と「1949年1月24日」は明確ですが、これらは確かに英語中心です。しかし、「月.abb」には、英語中心の値もあるので、:strptime(xx, f <- "%d $B %Y", tz = "GMT")またはstrptime(xx, f <- "%B $d %Y", tz = "GMT")戻り値の場合にそれらの値を一致させることができます。(month.abbドキュメントでは一致がロケール固有であるとドキュメントが言っているので、%Bへの一致に使用されることを意味していません。)
IRTFM

6
@CarlWitthoft私たちの何人かは時々つまずきます。私がダウンしている間、キックをありがとう。この質問で私はかなり多くのことを正しく理解しました:sessionInfo()を含め、検索し、検索内容を伝えてリンクを含め、できるだけ簡潔にしました。?as.Dateの1行を逃しましたが、TFMの扱いをしてくれました。私たちはいつでもあなたほど完璧になることはできません。
Matt Dowle、2013

1
@MatthewDowle懸命に降りてきてすみません。「合理的に十分に教育された人間にとって明白である」と「貧弱な無力なコードにとって明確である」とを混同しているように見えたときに、その狂気は始まったと思います。:-(
Carl Witthoft

回答:


66

これは文書化された動作です。から?as.Date

形式:文字列。指定されていない場合、最初の非「NA」要素で「 "%Y-%m-%d"」、次に「 "%Y /%m /%d"」が試行され、どちらも機能しない場合はエラーが発生します。

as.Date("01 Jan 2000")上記の2つの形式のいずれでもないため、エラーが発生します。 as.Date("01/01/2000")日付が上記の2つの形式のいずれでもないため、不正解が返されます。

「標準のあいまいさがない」とは「ISO-8601」を意味します(as.Date「%m /%d /%Y」はISO-8601ではないため、それほど厳密ではありません)。

このエラーが発生した場合の解決策は、で説明されている形式を使用して、日付(または日時)の形式を指定することです?strptime。変換はロケールに依存するため、データに日/月の名前や省略形が含まれている場合は、特に注意してください(の例と?strptimeを参照してください?LC_TIME)。


6
@BenBolkerどう"character string is not either %Y-%m-%d or %Y/%m/%d"ですか?
Matt Dowle 2013

9
動作は確かに?as.Date(+1)で文書化されています。ただし、「標準のあいまいでない形式」というエラーメッセージは、皮肉にもあいまいです。「形式が認識されません。ドキュメントを参照してください」などのより直接的なエラーメッセージは、ユーザーエクスペリエンスを向上させる可能性があります。また、 "01/01/2000"がISO-8601( "2000-01-01"はISO-8601)であるとは思わないため、あいまいさが増しています。
jthetzel 2013

@jthetzel:そうです、「01/01/2000」はISO-8601ではありません。個人的には、ISO-8601を標準の明確な形式であると考えています。そしてas.Date、「01/01/2000」について文句を言わないことはエラーメッセージと矛盾することに同意します。
Joshua Ulrich

31

言い換えれば、フォーマットを指定する必要があるよりも良い解決策はありますか?

はい、おかげで、(つまり、後半に2016年に)今そこにあるanytime::anydateから、いつでもパッケージが。

上記の例については、以下を参照してください。

R> anydate(c("01 Jan 2000", "01/01/2000", "2015/10/10"))
[1] "2000-01-01" "2000-01-01" "2015-10-10"
R> 

あなたが言ったように、これらは実際には明確であり、うまくいくはずです。そしてanydate()それらを介して。フォーマットなし。


2
ここに来たのは、不完全な形式で日付を解析しようとしているという別の質問があったからです。完全なもののために、私たちは今何かを持っています。私はこれに非常に満足しています-しつこい質問でした。言うまでもなく、anytime()も同様に役立ちPOSIXctます。
Dirk Eddelbuettel

随時パッケージを使用しただけで、かなりの数のNAを除いて、それは素晴らしい働きをしました。日付ベクトルでtrimws()を実行した後、すべてが完璧でした。
lawyeR 2017

私もメートルトンを使用します!
Dirk Eddelbuettel 2017

とてもシンプルに見えます!mm-dd(yyではない)の文字列値を持つ列でanydate()を使用しました。列のすべての<chr>値が正常に<date>に変換されました。残念ながら、それは年を「2020」ではなく「1400」に設定しました。_(ツ)_ /¯
owlstone

まあ、かなり。このサイトの他のいくつかの質問で答えたようにmm-dd、日付ではありません(mm-yyでもmm-yyyyでもありません)。そこにないものは解析できません。
Dirk Eddelbuettel

26

@JoshuaUlrichの回答の補足として、以下にfunctionの定義を示しますas.Date.character

as.Date.character
function (x, format = "", ...) 
{
    charToDate <- function(x) {
        xx <- x[1L]
        if (is.na(xx)) {
            j <- 1L
            while (is.na(xx) && (j <- j + 1L) <= length(x)) xx <- x[j]
            if (is.na(xx)) 
                f <- "%Y-%m-%d"
        }
        if (is.na(xx) || !is.na(strptime(xx, f <- "%Y-%m-%d", 
            tz = "GMT")) || !is.na(strptime(xx, f <- "%Y/%m/%d", 
            tz = "GMT"))) 
            return(strptime(x, f))
        stop("character string is not in a standard unambiguous format")
    }
    res <- if (missing(format)) 
        charToDate(x)
    else strptime(x, format, tz = "GMT")
    as.Date(res)
}
<bytecode: 0x265b0ec>
<environment: namespace:base>

だから、基本的には、両方の場合strptime(x, format="%Y-%m-%d")とはstrptime(x, format="%Y/%m/%d")スローNAそれが曖昧で明確でない場合と考えられています。


6

現在の形式を指定せずに日付を変換すると、このエラーが発生しやすくなります。

次に例を示します。

sdate <- "2015.10.10"

形式を指定せずに変換:

date <- as.Date(sdate4) # ==> This will generate the same error"""Error in charToDate(x): character string is not in a standard unambiguous format""".

指定した形式で変換:

date <- as.Date(sdate4, format = "%Y.%m.%d") # ==> Error Free Date Conversion.

2

これは、日付が以前にどのようにコード化されたかに関係なく、完全に機能します。

library(lubridate)
data$created_date1 <- mdy_hm(data$created_at)
data$created_date1 <- as.Date(data$created_date1)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.