Supposons une date spécifiée sous forme de trois nombres entiers: année, mois, jour
L'année est un entier à 4 chiffres (comme 2020), le mois est compris entre 1 et 12, le jour entre 1 et 31. p >
Je recherche une fonction simple (appelez-la checkdate) qui peut vérifier si une date est valide, renvoyant TRUE si elle est valide et FALSE si elle n'est pas valide.
Par exemple, checkdate (2008, 2, 29) renverrait TRUE car 2008 était une année bissextile.
En revanche, checkdate (2009, 2, 29) renverrait FALSE car 2009 n'était pas une année bissextile.
checkdate (2009, 6, 31) renverrait FALSE car juin n'a que 30 jours.
Etc.
MISE À JOUR
Basé sur la réponse de Dirk, ci-dessous, voici une fonction qui fait ce que j'ai demandé:
checkdate = function(y, m, d) {
#y: A year, not abbreviated to 2 digits.
#m: An integer in the range 1-12.
#d: An integer in the range 1-31.
#Convert to an R Date object.
#If the date is not valid, NA is returned.
dt = as.Date(paste(y, m, d, sep='-'), optional=TRUE)
ifelse(is.na(dt), FALSE, TRUE)
}
3 Réponses :
Bien sûr. Essayez simplement de l'analyser:
R> days <- 28:31
R> dates <- paste0("2020-02-", days)
R> as.Date(dates)
[1] "2020-02-28" "2020-02-29" NA NA
R>
Cela montre qu'en 2020, les 28 et 29 février existaient (année bissextile) mais pas les 30 et 31.
À partir de vous trois vecteurs vous pourrait utiliser sprintf ("% 4d-% 02d-% 02", y, m, d) pour créer un vecteur d'entrées de texte à analyser.
Votre solution fonctionne si j'utilise l'argument optionnel = TRUE dans l'appel à as.Date. Sinon, une erreur est générée.
Les deux solutions, de Ronak et Dirk, sont bien. Je vérifie la réponse de Dirk car elle ne nécessite pas l'utilisation d'un package tiers - juste base R.
Quelle version de R exécutez-vous? J'ai utilisé la fonction de base as.Date () pendant un milliard d'années et je n'ai jamais eu besoin de protéger pour / contre le NA. Je ne peux pas reproduire ce que vous dites ici. Mon exemple provenait d'une session standard "live" (dans R 4.0.1).
Essayez de convertir les entrées à ce jour si cela échoue, retournez FALSE.
checkdate <- function(y, m, d) {
tryCatch(lubridate::is.Date(as.Date(paste(y, m, d, sep = '-'))),
error = function(e) return(FALSE))
}
checkdate(2009, 6, 31)
#[1] FALSE
checkdate(2009, 2, 29)
#[1] FALSE
checkdate(2008, 2, 29)
#[1] TRUE
Je ne trouve aucune documentation pour is.Date. Est-ce peut-être votre fonction personnelle? Ou à partir d'une bibliothèque qui doit être installée?
Base R utilisant la logique de @Ronak Shah:
checkdate <- function(y, m, d) {
tryCatch(inherits(as.Date(paste(y, m, d, sep = '-')), "Date"),
error = function(e) return(FALSE))
}
checkdate(2015, 12, 31)