113 votes

Quels sont les formats de "date standard non ambiguë" pour la conversion des chaînes de caractères en date dans R ?

Veuillez considérer les points suivants

$ R --vanilla

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

Mais cette date est clairement es dans un format standard sans ambiguïté. Pourquoi ce message d'erreur ?

Pire encore, une date ambiguë est apparemment acceptée sans avertissement ni erreur et est ensuite lue de manière incorrecte !

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

J'ai cherché et trouvé 28 autres questions dans la balise [R] contenant ce message d'erreur. Toutes avec des solutions et des solutions de contournement impliquant la spécification du format, iiuc. Cette question est différente dans la mesure où je demande où sont définis les formats standard non ambigus et s'ils peuvent être modifiés. Tout le monde reçoit-il ces messages ou est-ce seulement moi ? Peut-être est-ce lié aux paramètres locaux ?

En d'autres termes, existe-t-il une meilleure solution que de devoir spécifier le format ?

29 questions contenant "[R] format standard sans ambiguïté".

> 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 votes

À en juger par la définition de la fonction de as.Date.character l'entrée n'est testée que pour ces deux formats : "%Y-%m-%d" y "%Y/%m/%d" . S'il peut correspondre à l'un d'entre eux, il semble être considéré comme "sans ambiguïté".

7 votes

@CarlWitthoft "Ai-je seulement lu" semble impliquer que la réponse est d'une évidence aveuglante dans ?as.Date . En quoi cela aide-t-il ?

0 votes

@plannapus Merci, cela semble être la réponse. Pourriez-vous l'ajouter afin que je puisse l'accepter.

74voto

Joshua Ulrich Points 68776

C'est un comportement documenté. De ?as.Date :

format : Une chaîne de caractères. S'il n'est pas spécifié, il essaiera '"%Y-%m-%d"' puis '"%Y/%m/%d"' sur le premier élément non 'NA', et donnera une erreur si aucun des deux ne fonctionne.

as.Date("01 Jan 2000") produit une erreur parce que le format n'est pas l'un des deux énumérés ci-dessus. as.Date("01/01/2000") donne une réponse incorrecte car la date n'est pas dans l'un des deux formats énumérés ci-dessus.

Je considère que "norme non ambiguë" signifie "ISO-8601" (bien que as.Date n'est pas si stricte, car "%m/%d/%Y" n'est pas ISO-8601).

Si vous recevez cette erreur, la solution est de spécifier le format de votre date (ou de vos dates), en utilisant les formats décrits dans la page Web de l'Office. Détails section dans ?strptime .

Assurez-vous que le commander de la spécification de conversion ainsi que tout séparateurs correspondent exactement au format de votre entrée ficelle. De plus, faites particulièrement attention si vos données contiennent des noms et/ou des abréviations de jour/mois, car la conversion dépendra de votre locale (voir les exemples dans la section ?strptime et lire ?LC_TIME ; voir aussi strptime , as.POSIXct y as.Date retour inattendu NA ).

6 votes

@BenBolker Que diriez-vous "character string is not either %Y-%m-%d or %Y/%m/%d" ?

9 votes

Ce comportement est certainement documenté dans ?as.Date (+1). Cependant, le message d'erreur "format standard non ambigu" est ironiquement ambigu, ce dont témoignent les 23 questions précédentes. Un message d'erreur plus direct comme "format non reconnu, voir documentation" pourrait améliorer l'expérience de l'utilisateur. De plus, je ne crois pas que "01/01/2000" soit ISO-8601 ("2000-01-01" est ISO-8601), ce qui ajoute à l'ambiguïté.

0 votes

@jthetzel : vous avez raison, "01/01/2000" n'est pas ISO-8601. Je voulais dire que je pense personnellement que la norme ISO-8601 est le format standard, sans ambiguïté. Et je suis d'accord pour dire que as.Date ne pas se plaindre de "01/01/2000" est incohérent avec le message d'erreur.

41voto

Dirk Eddelbuettel Points 134700

En d'autres termes, existe-t-il une meilleure solution que de devoir spécifier le format ?

Oui, c'est le cas maintenant (c'est-à-dire fin 2016), grâce à anytime::anydate de la à tout moment paquet.

Vous trouverez ci-dessous quelques exemples de ce qui précède :

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

Comme vous l'avez dit, ce sont en fait sans ambiguïté et devrait simplement fonctionner. Et via anydate() ils le font. Sans format.

2 votes

Je suis venu ici parce que nous avons eu une autre question sur quelque chose qui essaie d'analyser les dates avec un incomplet format. Pour les complets, nous avons maintenant quelque chose. J'en suis assez satisfait - c'était une question lancinante. Et inutile de le dire, anytime() est également utile pour POSIXct .

0 votes

Je viens d'utiliser le pack anytime et cela a fonctionné à merveille, à l'exception de quelques NA. Après avoir exécuté trimws() sur le vecteur date, tout était parfait.

1 votes

J'en utilise une tonne métrique aussi !

27voto

plannapus Points 9026

En complément de la réponse de @JoshuaUlrich, voici la définition de la fonction 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>

Donc, en gros, si les deux strptime(x, format="%Y-%m-%d") y strptime(x, format="%Y/%m/%d") lance un NA elle est considérée comme ambiguë et si elle n'est pas univoque.

8voto

Hassan3571619 Points 1

La conversion de la date sans spécifier le format actuel peut vous apporter cette erreur facilement.

Voici un exemple :

sdate <- "2015.10.10"

Convertir sans spécifier le format :

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

Convertir avec le format spécifié :

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

4voto

Viviana Wu Points 21

Cela fonctionne parfaitement pour moi, quelle que soit la façon dont la date était codée auparavant.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X