Manipulaciones de fecha usando as.POSIXlt
Pregunta
Estoy intentando localizar el domingo más cercano a hoy.
Yo defino hoy como:
dt <- as.Date("2014-06-04")
Puedo encontrar el último domingo siguiendo:
dt - as.POSIXlt(dt)$wday
[1] "2014-06-01"
Puedo encontrar el próximo domingo siguiendo:
dt + as.POSIXlt(dt)$wday
[1] "2014-06-07"
No estoy seguro de por qué lo siguiente no funciona:
ifelse(as.POSIXlt(dt)$wday <= 3,
dt - as.POSIXlt(dt)$wday,
dt + as.POSIXlt(dt)$wday)
[1] 16222
Me sale un numero: 16222
en lugar de una cita.
Cada una de las siguientes declaraciones funciona como se esperaba:
as.POSIXlt(dt)$wday
class(as.POSIXlt(dt)$wday)
as.POSIXlt(dt)$wday <= 3
¿¿Algunas ideas??
Solución
Parece que ifelse
devuelve un vector y tira la clase "POSIX" de sus fechas.¿Por qué no hacer
dt + ifelse(as.POSIXlt(dt)$wday <= 3, -1, 1) * as.POSIXlt(dt)$wday
en lugar.
Otros consejos
Otra solución: restaurar el atributo de la clase llamando a E.G.:
structure(ifelse(as.POSIXlt(dt)$wday <= 3,
dt - as.POSIXlt(dt)$wday,
dt + as.POSIXlt(dt)$wday), class="Date")
No es necesario utilizar un ifelse
aquí, un clásico if/else
hará el trabajo:
if(as.POSIXlt(dt)$wday <= 3) dt - as.POSIXlt(dt)$wday else dt + as.POSIXlt(dt)$wday
[1] "2014-06-01"
O incluso más simple:
wday <- as.POSIXlt(dt)$wday
dt + if(wday<= 3) -wday else wday
1) Prueba esto:
wday <- as.POSIXlt(dt)$wday
dt + ifelse(wday <= 3, -wday, 7-wday)
Esto aplica el ifelse
al número de días sumados o restados. ifelse
funciona bien con números simples pero no con tipos complejos como "Date"
clase por lo que esto evita la aplicación de ifelse
a "Date"
objetos de clase.
Tenga en cuenta que si wday > 3
entonces queremos agregar 7-wday
y no wday
(como en la pregunta).
La solución aquí sigue funcionando incluso si dt
es un vector de fechas.
2) Tenga en cuenta que la segunda línea de la respuesta en (1) podría escribirse alternativamente de la siguiente manera, que primero calcula el último domingo (dt-wday
) y suma 7 para obtener el próximo domingo si es el miércoles pasado de la semana.
dt - wday + ifelse(wday > 3, 7, 0)
3) Otra forma más de expresar esto es:
dt - wday + 7 * (wday > 3)