Proszę wziąć pod uwagę następujące kwestie
$ R --vanilla
> as.Date("01 Jan 2000")
Error in charToDate(x) :
character string is not in a standard unambiguous format
Ale ta data jest najwyraźniej w standardowym, jednoznacznym formacie. Dlaczego komunikat o błędzie?
Co gorsza, niejednoznaczna data jest najwyraźniej akceptowana bez ostrzeżenia lub błędu, a następnie odczytywana nieprawidłowo!
> as.Date("01/01/2000")
[1] "0001-01-20"
Przeszukałem i znalazłem 28 innych pytań w tagu [R] zawierającym ten komunikat o błędzie. Wszystko z rozwiązaniami i obejściami obejmującymi określenie formatu, iiuc. To pytanie jest inne, ponieważ pytam, gdzie i tak zdefiniowano standardowe, jednoznaczne formaty i czy można je zmienić? Czy wszyscy dostają te wiadomości, czy to tylko ja? Być może jest to związane z lokalizacją?
Innymi słowy, czy istnieje lepsze rozwiązanie niż konieczność określenia formatu?
29 pytań zawierających „[R] standardowy, jednoznaczny 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
as.Date.character
wejścia, jest testowany tylko dla tych dwóch formatów:"%Y-%m-%d"
i"%Y/%m/%d"
. Jeśli pasuje do jednego z nich, wydaje się, że jest to „jednoznaczne”.?as.Date
. Gdzie to pomaga?strptime(xx, f <- "%d $B %Y", tz = "GMT")
lubstrptime(xx, f <- "%B $d %Y", tz = "GMT")
zwrócone wartości. (Nie sugeruję, żemonth.abb
jest używany do dopasowania do% B, ponieważ dokumentacja mówi, że dopasowanie jest specyficzne dla ustawień regionalnych.)Odpowiedzi:
To jest udokumentowane zachowanie. Od
?as.Date
:as.Date("01 Jan 2000")
zwraca błąd, ponieważ format nie jest jednym z dwóch wymienionych powyżej.as.Date("01/01/2000")
zwraca nieprawidłową odpowiedź, ponieważ data nie jest w jednym z dwóch formatów wymienionych powyżej.Przyjmuję „standard jednoznaczny” jako „ISO-8601” (chociaż
as.Date
nie jest to aż tak ścisłe, ponieważ „% m /% d /% Y” nie jest ISO-8601).Jeśli pojawi się ten błąd, rozwiązaniem jest określenie formatu daty (lub godzin) przy użyciu formatów opisanych w
?strptime
. Zachowaj szczególną ostrożność, jeśli Twoje dane zawierają nazwy dni / miesięcy i / lub skróty, ponieważ konwersja będzie zależała od ustawień regionalnych (zobacz przykłady wi?strptime
przeczytaj?LC_TIME
).źródło
"character string is not either %Y-%m-%d or %Y/%m/%d"
??as.Date
(+1). Jednak komunikat o błędzie „standardowy, jednoznaczny format” jest ironicznie niejednoznaczny, o czym świadczą 23 poprzednie pytania. Bardziej bezpośredni komunikat o błędzie, np. „Format nierozpoznany, zobacz dokumentację”, może poprawić komfort użytkowania. Nie uważam też, że „01/01/2000” to ISO-8601 („2000-01-01” to ISO-8601), co zwiększa niejednoznaczność.as.Date
nie narzekanie na „01/01/2000” jest niezgodne z komunikatem o błędzie.Tak, jest teraz (tj. Pod koniec 2016 r.), Dzięki
anytime::anydate
z pakietu Anytime .Poniżej znajdziesz kilka przykładów z góry:
R> anydate(c("01 Jan 2000", "01/01/2000", "2015/10/10")) [1] "2000-01-01" "2000-01-01" "2015-10-10" R>
Jak powiedziałeś, są one w rzeczywistości jednoznaczne i powinny po prostu działać. I przez
anydate()
nich robią. Bez formatu.źródło
anytime()
jest równie przydatny dlaPOSIXct
.mm-dd
nie jest datą (ani mm-rr, ani mm-rrrr). Nie możesz przeanalizować tego, czego tam nie ma.Jako uzupełnienie odpowiedzi @JoshuaUlrich, oto definicja funkcji
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>
Zasadniczo więc, jeśli oba
strptime(x, format="%Y-%m-%d")
istrptime(x, format="%Y/%m/%d")
rzucaNA
, jest uważane za niejednoznaczne, a jeśli nie jednoznaczne.źródło
Konwersja daty bez określenia bieżącego formatu może łatwo przynieść ten błąd.
Oto przykład:
sdate <- "2015.10.10"
Konwertuj bez określania formatu:
date <- as.Date(sdate4) # ==> This will generate the same error"""Error in charToDate(x): character string is not in a standard unambiguous format""".
Konwertuj w określonym formacie:
date <- as.Date(sdate4, format = "%Y.%m.%d") # ==> Error Free Date Conversion.
źródło
U mnie działa to idealnie, bez względu na to, jak wcześniej zakodowano datę.
library(lubridate) data$created_date1 <- mdy_hm(data$created_at) data$created_date1 <- as.Date(data$created_date1)
źródło