Манипуляции с датами с использованием as.POSIXlt

StackOverflow https://stackoverflow.com//questions/24046759

  •  21-12-2019
  •  | 
  •  

Вопрос

Я пытаюсь найти ближайшее к сегодняшнему воскресенью.

Я определяю сегодняшний день как:

dt <- as.Date("2014-06-04")

Я могу найти последнее воскресенье следующим образом:

dt - as.POSIXlt(dt)$wday
[1] "2014-06-01"

Я могу найти следующее воскресенье следующим образом:

dt + as.POSIXlt(dt)$wday
[1] "2014-06-07"

Не знаю, почему следующее не работает:

ifelse(as.POSIXlt(dt)$wday <= 3, 
       dt - as.POSIXlt(dt)$wday, 
       dt + as.POSIXlt(dt)$wday)
[1] 16222

Я получаю номер: 16222 вместо свидания.

Каждое из следующих утверждений работает ожидаемым образом:

as.POSIXlt(dt)$wday
class(as.POSIXlt(dt)$wday)
as.POSIXlt(dt)$wday <= 3

Есть идеи??

Это было полезно?

Решение

Кажется, что ifelse возвращает вектор и удаляет класс «POSIX» из ваших дат.Почему бы не сделать

dt + ifelse(as.POSIXlt(dt)$wday <= 3, -1, 1) * as.POSIXlt(dt)$wday

вместо.

Другие советы

Другое решение:восстановите атрибут класса, вызвав, например:

structure(ifelse(as.POSIXlt(dt)$wday <= 3, 
       dt - as.POSIXlt(dt)$wday, 
       dt + as.POSIXlt(dt)$wday), class="Date")

Нет необходимости использовать ifelse вот, классика if/else выполню работу:

if(as.POSIXlt(dt)$wday <= 3) dt - as.POSIXlt(dt)$wday else dt + as.POSIXlt(dt)$wday
[1] "2014-06-01"

Или еще проще:

wday <- as.POSIXlt(dt)$wday 
dt + if(wday<= 3) -wday else wday

1) Попробуй это:

wday <- as.POSIXlt(dt)$wday
dt + ifelse(wday <= 3, -wday, 7-wday)

Это касается ifelse к количеству добавленных или вычтенных дней. ifelse хорошо работает с простыми числами, но не со сложными типами, такими как "Date" class, поэтому это позволяет избежать применения ifelse к "Date" объекты класса.

Обратите внимание, что если wday > 3 тогда мы хотим добавить 7-wday и не wday (как в вопросе).

Решение здесь продолжает работать, даже если dt представляет собой вектор дат.

2) Обратите внимание, что вторую строку ответа в (1) можно альтернативно записать следующим образом, при котором сначала вычисляется последнее воскресенье (dt-wday) и добавляет 7, чтобы получить следующее воскресенье, если это прошлая среда недели.

dt - wday + ifelse(wday > 3, 7, 0)

3) Еще один способ выразить это:

dt - wday + 7 * (wday > 3)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top