Quais são os formatos de “data padrão inequívoca” para a conversão de string até a data em R?


94

Por favor, considere o seguinte

$ R --vanilla

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

Mas essa data está claramente em um formato padrão não ambíguo. Por que a mensagem de erro?

Pior, uma data ambígua é aparentemente aceita sem aviso ou erro e então lida incorretamente!

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

Eu pesquisei e encontrei 28 outras questões na tag [R] contendo esta mensagem de erro. Tudo com soluções e soluções alternativas envolvendo a especificação do formato, iiuc. Esta pergunta é diferente, pois estou perguntando onde estão os formatos padrão inequívocos definidos de qualquer maneira e eles podem ser alterados? Todos recebem essas mensagens ou sou só eu? Talvez seja relacionado ao local?

Em outras palavras, existe uma solução melhor do que precisar especificar o formato?

29 questões contendo "[R] formato não ambíguo padrão"

> 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
a julgar pela definição da função da as.Date.characterentrada só é testado para estes dois formatos: "%Y-%m-%d"e "%Y/%m/%d". Se puder corresponder a um deles, parece ser considerado "inequívoco".
— plannapus

7
@CarlWitthoft "Será que eu li" parece implicar que a resposta é incrivelmente óbvia em ?as.Date. Onde isso ajuda com isso?
— Matt Dowle

2
Indiscutivelmente, "24 de janeiro de 1949" e "24 de janeiro de 1949" seriam inequívocos, mas certamente são anglo-centrados. No entanto, também existem valores para 'month.abb' que também são anglo-centrados, então um caso pode ser feito para esses valores serem correspondidos em casos onde: strptime(xx, f <- "%d $B %Y", tz = "GMT")ou strptime(xx, f <- "%B $d %Y", tz = "GMT")valores retornados. (Não estou sugerindo que month.abbseja usado para a correspondência com% B, pois os documentos dizem que a correspondência é específica do local.)
— IRTFM

6
@CarlWitthoft Alguns de nós tropeçam de vez em quando. Obrigado pelo chute enquanto estou no chão. Nesta pergunta acertei algumas coisas: incluí sessionInfo (), pesquisei, contei o que pesquisei e incluí um link, mantive-o o mais consistente possível. Perdi uma linha em? As.Date e você me dá o tratamento TFM. Não podemos ser todos tão perfeitos quanto você o tempo todo.
— Matt Dowle

1
@MatthewDowle, desculpe se desisti muito. Acho que a flamosidade começou quando você pareceu confundir "inequívoco para um ser humano razoavelmente bem-educado" com "inequívoco para um pedaço de código pobre e indefeso". :-(
— Carl Witthoft

Respostas:


66

Este é um comportamento documentado. De ?as.Date:

formato: uma sequência de caracteres. Se não for especificado, ele tentará '"% Y-% m-% d"' então '"% Y /% m /% d"' no primeiro elemento não'NA 'e dará um erro se nenhum dos dois funcionar.

as.Date("01 Jan 2000")produz um erro porque o formato não é um dos dois listados acima. as.Date("01/01/2000")produz uma resposta incorreta porque a data não está em um dos dois formatos listados acima.

Eu considero "padrão inequívoco" como "ISO-8601" (embora as.Datenão seja tão estrito, já que "% m /% d /% Y" não é ISO-8601).

Se você receber esse erro, a solução é especificar o formato de sua data (ou horários), usando os formatos descritos em ?strptime. Tenha cuidado especial se seus dados contiverem nomes e / ou abreviações de dias / meses, pois a conversão dependerá de sua localidade (veja os exemplos em ?strptimee leia ?LC_TIME).


6
@BenBolker Que tal "character string is not either %Y-%m-%d or %Y/%m/%d"?
— Matt Dowle

9
O comportamento certamente está documentado em ?as.Date(+1). No entanto, a mensagem de erro "formato não ambíguo padrão" é ironicamente ambígua, como atestam as 23 questões anteriores. Uma mensagem de erro mais direta como "formato não reconhecido, consulte a documentação" pode melhorar a experiência do usuário. Além disso, não acredito que "01/01/2000" seja ISO-8601 ("2000-01-01" é ISO-8601), o que aumenta a ambiguidade.
— jthetzel

@jthetzel: você está certo, "01/01/2000" não é ISO-8601. Eu quis dizer que pessoalmente penso no ISO-8601 como o formato padrão e inequívoco. E eu concordo que as.Datenão reclamar de "01/01/2000" é inconsistente com a mensagem de erro.
— Joshua Ulrich

31

Em outras palavras, existe uma solução melhor do que precisar especificar o formato?

Sim, existe agora (ou seja, no final de 2016), graças a anytime::anydatepartir do momento embalagem.

Veja o seguinte para alguns exemplos acima:

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

Como você disse, eles não são ambíguos e devem funcionar. E via anydate()eles fazem. Sem formato.


2
Só vim aqui porque tínhamos outra dúvida de algo tentando analisar datas com um formato incompleto . Para completos, agora temos algo. Estou muito satisfeito com isso - era uma pergunta incômoda. E nem anytime()é preciso dizer que é igualmente útil para POSIXct.
— Dirk Eddelbuettel de

Apenas usei o pacote Anytime e funcionou maravilhosamente, exceto em alguns NAs. Depois de executar trimws () no vetor data, tudo ficou perfeito.
— lawyeR

Eu também uso uma tonelada!
— Dirk Eddelbuettel

Parece tão simples! Eu usei anydate () em uma coluna com valores de string de mm-dd (sem aa). Todos os valores <chr> na coluna foram convertidos com êxito para <data>. Infelizmente, ele definiu o ano como '1400' em vez de '2020'. ¯_ (ツ) _ / ¯
— owlstone

Bem, não exatamente. Como respondi em algumas outras perguntas neste site, mm-ddnão é uma data (nem é mm-aa ou mm-aaaa). Você não pode analisar o que não está lá.
— Dirk Eddelbuettel

26

Como complemento à resposta de @JoshuaUlrich, aqui está a definição de função 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>

Então, basicamente, se strptime(x, format="%Y-%m-%d")e strptime(x, format="%Y/%m/%d")lançar um NA, é considerado ambíguo e, se não inequívoco.


6

Converter a data sem especificar o formato atual pode trazer esse erro para você facilmente.

Aqui está um exemplo:

sdate <- "2015.10.10"

Converta sem especificar o formato:

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

Converter com o formato especificado:

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

2

Isso funciona perfeitamente para mim, não importa como a data foi codificada anteriormente.

library(lubridate)
data$created_date1 <- mdy_hm(data$created_at)
data$created_date1 <- as.Date(data$created_date1)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.