Was sind die "Standard eindeutigen Datumsformate" für die Konvertierung von Zeichenfolgen in Datumsangaben in R?

92

Bitte beachten Sie Folgendes

$ R --vanilla

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

Aber zu diesem Zeitpunkt klar ist in einem Standard - Format eindeutig. Warum die Fehlermeldung?

Schlimmer noch, ein mehrdeutiges Datum wird anscheinend ohne Vorwarnung oder Fehler akzeptiert und dann falsch gelesen!

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

Ich habe 28 andere Fragen im [R] -Tag gesucht und gefunden, die diese Fehlermeldung enthalten. Alle mit Lösungen und Problemumgehungen, bei denen das Format angegeben wird, iiuc. Diese Frage unterscheidet sich darin, dass ich frage, wo die standardmäßigen eindeutigen Formate überhaupt definiert sind und ob sie geändert werden können. Bekommt jeder diese Nachrichten oder bin es nur ich? Vielleicht hängt es mit dem Gebietsschema zusammen?

Mit anderen Worten, gibt es eine bessere Lösung, als das Format angeben zu müssen?

29 Fragen mit "[R] Standard eindeutiges Format"

> 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
Matt Dowle
quelle
13
Nach der Funktionsdefinition as.Date.characterder Eingabe zu urteilen, wird nur für diese beiden Formate getestet: "%Y-%m-%d"und "%Y/%m/%d". Wenn es mit einem von ihnen übereinstimmen kann, scheint es als "eindeutig" zu gelten.
Planapus
7
@CarlWitthoft "Habe ich überhaupt gelesen" scheint zu implizieren, dass die Antwort in blindlings offensichtlich ist ?as.Date. Wo hilft es dabei?
Matt Dowle
2
"24. Januar 1949" und "24. Januar 1949" wären wohl eindeutig, aber sie sind sicherlich anglozentrisch. Es gibt jedoch auch Werte für 'month.abb', die ebenfalls anglozentrisch sind. Daher könnte ein Fall angeführt werden, dass diese Werte in Fällen übereinstimmen, in denen: strptime(xx, f <- "%d $B %Y", tz = "GMT")oder strptime(xx, f <- "%B $d %Y", tz = "GMT")Werte zurückgegeben werden. (Ich impliziere nicht, dass dies month.abbfür das Matching mit% B verwendet wird, da die Dokumente sagen, dass das Matching länderspezifisch ist.)
IRTFM
6
@CarlWitthoft Einige von uns stolpern hin und wieder. Danke für den Kick, während ich unten bin. In dieser Frage habe ich einige Dinge richtig gemacht: Ich habe sessionInfo () aufgenommen, gesucht, Ihnen gesagt, was ich gesucht habe, und einen Link eingefügt. Ich habe ihn so übersichtlich wie möglich gehalten. Ich habe eine Zeile in? As.Date verpasst und Sie geben mir die TFM-Behandlung. Wir können nicht immer so perfekt sein wie Sie.
Matt Dowle
1
@ MatthewDowle Entschuldigung, wenn ich hart runtergekommen bin. Ich denke, die Flamosität begann, als Sie "eindeutig für einen einigermaßen gut ausgebildeten Menschen" mit "eindeutig für einen armen hilflosen Code" zu verwechseln schienen. :-(
Carl Witthoft

Antworten:

65

Dies ist dokumentiertes Verhalten. Von ?as.Date:

Format: Eine Zeichenfolge. Wenn nicht angegeben, wird ''% Y-% m-% d "'und dann'"% Y /% m /% d "'für das erste Nicht-'NA'-Element versucht und ein Fehler ausgegeben, wenn keines funktioniert.

as.Date("01 Jan 2000")gibt einen Fehler aus, da das Format nicht eines der beiden oben aufgeführten ist. as.Date("01/01/2000")ergibt eine falsche Antwort, da das Datum nicht in einem der beiden oben aufgeführten Formate vorliegt.

Ich verstehe "Standard eindeutig" als "ISO-8601" (obwohl dies as.Datenicht so streng ist, da "% m /% d /% Y" nicht ISO-8601 ist).

Wenn Sie diesen Fehler erhalten, besteht die Lösung darin, das Format Ihres Datums (oder Ihrer Datums- / Uhrzeitangaben) in den unter beschriebenen Formaten anzugeben ?strptime. Seien Sie besonders vorsichtig, wenn Ihre Daten Tages- / Monatsnamen und / oder Abkürzungen enthalten, da die Konvertierung von Ihrem Gebietsschema abhängt (siehe Beispiele in ?strptimeund lesen Sie ?LC_TIME).

Joshua Ulrich
quelle
6
@ BenBolker Wie wäre es "character string is not either %Y-%m-%d or %Y/%m/%d"?
Matt Dowle
9
Das Verhalten ist sicherlich in ?as.Date(+1) dokumentiert . Die Fehlermeldung "Standard eindeutiges Format" ist jedoch ironischerweise mehrdeutig, was die 23 vorherigen Fragen bestätigen. Eine direktere Fehlermeldung wie "Format nicht erkannt, siehe Dokumentation" kann die Benutzererfahrung verbessern. Ich glaube auch nicht, dass "01/01/2000" ISO-8601 ist ("2000-01-01" ist ISO-8601), was die Mehrdeutigkeit erhöht.
Jthetzel
@jthetzel: Sie haben Recht, "01/01/2000" ist nicht ISO-8601. Ich persönlich meinte, ISO-8601 sei das eindeutige Standardformat. Und ich stimme zu, dass es as.Datenicht mit der Fehlermeldung vereinbar ist, sich nicht über "01/01/2000" zu beschweren.
Joshua Ulrich
31

Mit anderen Worten, gibt es eine bessere Lösung, als das Format angeben zu müssen?

Ja, es gibt jetzt (dh Ende 2016) dank anytime::anydatedes jederzeit verfügbaren Pakets.

Im Folgenden finden Sie einige Beispiele von oben:

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

Wie Sie sagten, sind diese in der Tat eindeutig und sollten einfach funktionieren. Und über anydate()sie. Ohne Format.

Dirk Eddelbuettel
quelle
2
Kam nur hierher, weil wir eine andere Frage hatten, bei der versucht wurde, Daten mit einem unvollständigen Format zu analysieren . Für vollständige haben wir jetzt etwas. Ich bin sehr zufrieden damit - es war eine heikle Frage. Und natürlich anytime()ist es ebenso nützlich für POSIXct.
Dirk Eddelbuettel
Ich habe gerade das jederzeitige Paket verwendet und es hat wunderbar funktioniert, mit Ausnahme einiger NAs. Nachdem ich trimws () für den Datumsvektor ausgeführt hatte, war alles perfekt.
lawyeR
Ich benutze es auch eine Tonne!
Dirk Eddelbuettel
Sieht so einfach aus! Ich habe anydate () für eine Spalte mit Zeichenfolgenwerten von mm-tt (nein jj) verwendet. Alle <chr> -Werte in der Spalte wurden erfolgreich in <date> konvertiert. Leider wurde das Jahr auf "1400" anstatt auf "2020" gesetzt. ¯_ (ツ) _ / ¯
Eulenstein
Nicht ganz. Wie ich in ein paar anderen Fragen auf dieser Seite beantwortet habe, mm-ddist kein Datum (auch nicht MM-JJ oder MM-JJJJ). Sie können nicht analysieren, was es nicht gibt.
Dirk Eddelbuettel
26

Als Ergänzung zur Antwort von @JoshuaUlrich folgt hier die Definition der Funktion 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>

Wenn also beides strptime(x, format="%Y-%m-%d")und ein strptime(x, format="%Y/%m/%d")geworfen wird NA, wird es als mehrdeutig und wenn nicht eindeutig angesehen.

Planapus
quelle
6

Das Konvertieren des Datums ohne Angabe des aktuellen Formats kann diesen Fehler leicht verursachen.

Hier ist ein Beispiel:

sdate <- "2015.10.10"

Konvertieren ohne Angabe des Formats:

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

Mit angegebenem Format konvertieren:

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

Dies funktioniert perfekt für mich, egal wie das Datum zuvor codiert wurde.

library(lubridate)
data$created_date1 <- mdy_hm(data$created_at)
data$created_date1 <- as.Date(data$created_date1)
Viviana Wu
quelle