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')

Вы могли бы принудить lubridatePeriod объект класса к 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.

Другие вопросы по тегам