Manipulations de dates à l'aide de as.POSIXlt
Question
J'essaie de localiser le dimanche le plus proche d'aujourd'hui.
Je définis aujourd'hui comme :
dt <- as.Date("2014-06-04")
Je peux retrouver le dernier dimanche en suivant :
dt - as.POSIXlt(dt)$wday
[1] "2014-06-01"
Je peux trouver le dimanche prochain en suivant :
dt + as.POSIXlt(dt)$wday
[1] "2014-06-07"
Je ne sais pas pourquoi les éléments suivants ne fonctionnent pas :
ifelse(as.POSIXlt(dt)$wday <= 3,
dt - as.POSIXlt(dt)$wday,
dt + as.POSIXlt(dt)$wday)
[1] 16222
J'obtiens un numéro : 16222
au lieu d'un rendez-vous.
Chacune des instructions suivantes fonctionne comme prévu :
as.POSIXlt(dt)$wday
class(as.POSIXlt(dt)$wday)
as.POSIXlt(dt)$wday <= 3
Des idées??
La solution
Il semble que ifelse
renvoie un vecteur et supprime la classe "POSIX" de vos dates.Pourquoi ne pas faire
dt + ifelse(as.POSIXlt(dt)$wday <= 3, -1, 1) * as.POSIXlt(dt)$wday
plutôt.
Autres conseils
Une autre solution:restaurez l'attribut de classe en appelant par exemple :
structure(ifelse(as.POSIXlt(dt)$wday <= 3,
dt - as.POSIXlt(dt)$wday,
dt + as.POSIXlt(dt)$wday), class="Date")
Pas besoin d'utiliser un ifelse
ici, un classique if/else
fera le travail:
if(as.POSIXlt(dt)$wday <= 3) dt - as.POSIXlt(dt)$wday else dt + as.POSIXlt(dt)$wday
[1] "2014-06-01"
Ou encore plus simple :
wday <- as.POSIXlt(dt)$wday
dt + if(wday<= 3) -wday else wday
1) Essaye ça:
wday <- as.POSIXlt(dt)$wday
dt + ifelse(wday <= 3, -wday, 7-wday)
Ceci s'applique au ifelse
au nombre de jours ajoutés ou soustraits. ifelse
fonctionne bien avec des nombres simples mais pas avec des types complexes comme "Date"
classe donc cela évite l'application de ifelse
à "Date"
objets de classe.
Notez que si wday > 3
alors nous voulons ajouter 7-wday
et pas wday
(comme dans la question).
La solution ici continue de fonctionner même si dt
est un vecteur de dates.
2) Notez que la deuxième ligne de la réponse en (1) pourrait alternativement être écrite de la manière suivante qui calcule d'abord le dernier dimanche (dt-wday
) et ajoute 7 pour obtenir le dimanche suivant si c'est le mercredi dernier de la semaine.
dt - wday + ifelse(wday > 3, 7, 0)
3) Une autre façon d’exprimer cela est :
dt - wday + 7 * (wday > 3)