R последовательность дат с lubridate
Привет я пытаюсь получить последовательность дат с lubridate
Это не работает
seq(ymd('2012-04-07'),ymd('2013-03-22'),by=week(1))
базовая команда
seq(as.Date('2012-04-7'),as.Date('2013-03-22'),'weeks')
делает, но я хотел бы знать, если есть элегантный способ сделать это с lubridate.
РЕДАКТИРОВАТЬ
Пожалуйста, не обращайте внимания: решил сам, оставив только для потомков. Рад удалить это, если это необходимо.
seq(ymd('2012-04-07'),ymd('2013-03-22'),by='weeks')
Делает трюк
3 ответа
ymd
является оберткой для разбора строк даты и возвращает POSIXct
объект.
Вам просто нужно использовать стандартную терминологию, описанную в ?seq.POSIXt
(не lubridate
) определить недели
seq(ymd('2012-04-07'),ymd('2013-03-22'), by = '1 week')
seq(ymd('2012-04-07'),ymd('2013-03-22'), by = 'weeks')
будет работать
как будет
seq(ymd('2012-04-07'),ymd('2013-03-22'), by = '2 week')
Вы могли бы принудить lubridate
Period
объект класса к difftime
но это кажется довольно ненужным
seq(ymd('2012-04-07'),ymd('2013-03-22'), by = as.difftime(weeks(1)))
Это способ придерживаться POSIXct
вселенная lubridate
и не меняйте формат даты на базу R POSIXt
, Я избегаю изменения формата даты в моих сценариях, потому что нахожу, что это обычное место, где появляются ошибки (например, изменения часового пояса или потеря меток времени). Из этого следует совет %m+%
: R: добавление 1 месяца к дате
# example date is a leap day for a "worst case scenario"
library("lubridate")
posixct.in <- parse_date_time(x = "2016-02-29", orders = "ymd")
# [1] "2016-02-29 UTC"
posixct.seq <- posixct.in %m+% years(x = seq.int(from = 0, to = 3, by = 1))
# [1] "2016-02-29 UTC" "2017-02-28 UTC" "2018-02-28 UTC" "2019-02-28 UTC"
posixct.seq <- posixct.in %m+% months(x = seq.int(from = 0, to = 3, by = 1))
# [1] "2016-02-29 UTC" "2016-03-29 UTC" "2016-04-29 UTC" "2016-05-29 UTC"
posixct.seq <- posixct.in %m+% days(x = seq.int(from = 0, to = 3, by = 1))
# [1] "2016-02-29 UTC" "2016-03-01 UTC" "2016-03-02 UTC" "2016-03-03 UTC"
posixct.seq <- posixct.in %m+% weeks(x = seq.int(from = 0, to = 3, by = 1))
# [1] "2016-02-29 UTC" "2016-03-07 UTC" "2016-03-14 UTC" "2016-03-21 UTC"
Обычный +
тоже иногда работает, но %m+%
предотвращает такие ошибки:
posixct.seq <- posixct.in + years(x = seq.int(from = 0, to = 3, by = 1))
# [1] "2016-02-29 UTC" NA NA NA
Сначала я был смущен, потому что я думал %m+
был просто способ добавить месяцы и тому подобное lubridate
такие команды, как %y+%
и т.д. не существует. Но, оказывается, "м" не означает "сложение месяца". Моя лучшая догадка "магия" =)
Это может быть полезно для других, а может и нет, но я написал более общую функцию для расчета последовательности дат, используя комбинацию смазки, базы и изменения времени. Он допускает арифметику периода или продолжительности (базовую).
# remotes::install_github("NicChr/timeplyr")
library(timeplyr)
library(lubridate)
#>
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#>
#> date, intersect, setdiff, union
seq(ymd('2012-04-07'),ymd('2013-03-22'),by='weeks')
#> [1] "2012-04-07" "2012-04-14" "2012-04-21" "2012-04-28" "2012-05-05"
#> [6] "2012-05-12" "2012-05-19" "2012-05-26" "2012-06-02" "2012-06-09"
#> [11] "2012-06-16" "2012-06-23" "2012-06-30" "2012-07-07" "2012-07-14"
#> [16] "2012-07-21" "2012-07-28" "2012-08-04" "2012-08-11" "2012-08-18"
#> [21] "2012-08-25" "2012-09-01" "2012-09-08" "2012-09-15" "2012-09-22"
#> [26] "2012-09-29" "2012-10-06" "2012-10-13" "2012-10-20" "2012-10-27"
#> [31] "2012-11-03" "2012-11-10" "2012-11-17" "2012-11-24" "2012-12-01"
#> [36] "2012-12-08" "2012-12-15" "2012-12-22" "2012-12-29" "2013-01-05"
#> [41] "2013-01-12" "2013-01-19" "2013-01-26" "2013-02-02" "2013-02-09"
#> [46] "2013-02-16" "2013-02-23" "2013-03-02" "2013-03-09" "2013-03-16"
time_seq(ymd('2012-04-07'),ymd('2013-03-22'),by='weeks')
#> [1] "2012-04-07" "2012-04-14" "2012-04-21" "2012-04-28" "2012-05-05"
#> [6] "2012-05-12" "2012-05-19" "2012-05-26" "2012-06-02" "2012-06-09"
#> [11] "2012-06-16" "2012-06-23" "2012-06-30" "2012-07-07" "2012-07-14"
#> [16] "2012-07-21" "2012-07-28" "2012-08-04" "2012-08-11" "2012-08-18"
#> [21] "2012-08-25" "2012-09-01" "2012-09-08" "2012-09-15" "2012-09-22"
#> [26] "2012-09-29" "2012-10-06" "2012-10-13" "2012-10-20" "2012-10-27"
#> [31] "2012-11-03" "2012-11-10" "2012-11-17" "2012-11-24" "2012-12-01"
#> [36] "2012-12-08" "2012-12-15" "2012-12-22" "2012-12-29" "2013-01-05"
#> [41] "2013-01-12" "2013-01-19" "2013-01-26" "2013-02-02" "2013-02-09"
#> [46] "2013-02-16" "2013-02-23" "2013-03-02" "2013-03-09" "2013-03-16"
# Months example
# Notice the difference between seq and time_seq
time_seq(dmy("31-01-2012"), dmy("31-01-2013"), by = "month")
#> [1] "2012-01-31" "2012-02-29" "2012-03-31" "2012-04-30" "2012-05-31"
#> [6] "2012-06-30" "2012-07-31" "2012-08-31" "2012-09-30" "2012-10-31"
#> [11] "2012-11-30" "2012-12-31" "2013-01-31"
seq(dmy("31-01-2012"), dmy("31-01-2013"), by = "month")
#> [1] "2012-01-31" "2012-03-02" "2012-03-31" "2012-05-01" "2012-05-31"
#> [6] "2012-07-01" "2012-07-31" "2012-08-31" "2012-10-01" "2012-10-31"
#> [11] "2012-12-01" "2012-12-31" "2013-01-31"
# DST example
dst <- dmy_hms("26-03-2023 00:00:00", tz = "GB")
# Base R
seq(dst, length.out = 5,
by = "hour")
#> [1] "2023-03-26 00:00:00 GMT" "2023-03-26 02:00:00 BST"
#> [3] "2023-03-26 03:00:00 BST" "2023-03-26 04:00:00 BST"
#> [5] "2023-03-26 05:00:00 BST"
time_seq(dst, length.out = 5,
by = "hour",
seq_type = "duration")
#> [1] "2023-03-26 00:00:00 GMT" "2023-03-26 02:00:00 BST"
#> [3] "2023-03-26 03:00:00 BST" "2023-03-26 04:00:00 BST"
#> [5] "2023-03-26 05:00:00 BST"
# Period arithmetic
time_seq(dst, length.out = 5,
roll_dst = "NA",
by = "hour",
seq_type = "period")
#> [1] "2023-03-26 00:00:00 GMT" NA
#> [3] "2023-03-26 02:00:00 BST" "2023-03-26 03:00:00 BST"
#> [5] "2023-03-26 04:00:00 BST"
time_seq(dst, length.out = 5,
roll_dst = "pre",
by = "hour",
seq_type = "period")
#> [1] "2023-03-26 00:00:00 GMT" "2023-03-26 00:00:00 GMT"
#> [3] "2023-03-26 02:00:00 BST" "2023-03-26 03:00:00 BST"
#> [5] "2023-03-26 04:00:00 BST"
time_seq(dst, length.out = 5,
roll_dst = "post",
by = "hour",
seq_type = "period")
#> [1] "2023-03-26 00:00:00 GMT" "2023-03-26 02:00:00 BST"
#> [3] "2023-03-26 02:00:00 BST" "2023-03-26 03:00:00 BST"
#> [5] "2023-03-26 04:00:00 BST"
# You can also mix dates and datetimes
seq(ymd('2012-04-07'), now(), by = "years")
#> Error in seq.Date(ymd("2012-04-07"), now(), by = "years"): 'to' must be a "Date" object
time_seq(ymd('2012-04-07'), now(), by = "years")
#> [1] "2012-04-07 UTC" "2013-04-07 UTC" "2014-04-07 UTC" "2015-04-07 UTC"
#> [5] "2016-04-07 UTC" "2017-04-07 UTC" "2018-04-07 UTC" "2019-04-07 UTC"
#> [9] "2020-04-07 UTC" "2021-04-07 UTC" "2022-04-07 UTC"
Создано 28 марта 2023 г. с использованием reprex v2.0.2.