Convert a tbl_time object from daily to monthly, from minute data to hourly, and more. This allows the user to easily aggregate data to a less granular level by taking the value from either the beginning or end of the period.

as_period(.tbl_time, period = "yearly", start_date = NULL, side = "start",
  include_endpoints = FALSE, ...)

Arguments

.tbl_time

A tbl_time object.

period

A character specification used for time-based grouping. The general format to use is "frequency period" where frequency is a number like 1 or 2, and period is an interval like weekly or yearly. There must be a space between the two.

Note that you can pass the specification in a flexible way:

  • 1 Year: '1 year' / '1 Y' / '1 yearly' / 'yearly'

This shorthand is available for year, quarter, month, day, hour, minute, second, millisecond and microsecond periodicities.

Additionally, you have the option of passing in a vector of dates to use as custom and more flexible boundaries.

start_date

Optional argument used to specify the start date for the first group. The default is to start at the closest period boundary below the minimum date in the supplied index.

side

Whether to return the date at the beginning or the end of the new period. By default, the "start" of the period. Use "end" to change to the end of the period.

include_endpoints

Whether to include the first or last data point in addition to the transformed data.

...

Not currently used.

Details

This function respects dplyr::group_by() groups.

The side argument is useful when you want to return data at, say, the end of a quarter, or the end of a month. include_endpoints can be useful when calculating a change over time. In addition to changing to monthly dates, you often need the first data point as a baseline for the first calculation.

Examples

# Basic usage --------------------------------------------------------------- # FB stock prices data(FB) FB <- as_tbl_time(FB, date) # Aggregate FB to yearly data as_period(FB, "yearly")
#> # A time tibble: 4 x 8 #> # Index: date #> symbol date open high low close volume adjusted #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-01-02 27.4 28.2 27.4 28.0 69846400 28.0 #> 2 FB 2014-01-02 54.8 55.2 54.2 54.7 43195500 54.7 #> 3 FB 2015-01-02 78.6 78.9 77.7 78.4 18177500 78.4 #> 4 FB 2016-01-04 102 102 99.8 102 37912400 102
# Aggregate FB to every 2 years as_period(FB, "2 years")
#> # A time tibble: 3 x 8 #> # Index: date #> symbol date open high low close volume adjusted #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-01-02 27.4 28.2 27.4 28.0 69846400 28.0 #> 2 FB 2014-01-02 54.8 55.2 54.2 54.7 43195500 54.7 #> 3 FB 2016-01-04 102 102 99.8 102 37912400 102
# Aggregate FB to yearly data, but use the last data point available # in that period as_period(FB, "yearly", side = "end")
#> # A time tibble: 4 x 8 #> # Index: date #> symbol date open high low close volume adjusted #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-12-31 54.1 54.9 53.9 54.7 43076200 54.7 #> 2 FB 2014-12-31 79.5 79.8 77.9 78.0 19935400 78.0 #> 3 FB 2015-12-31 106 106 105 105 18298700 105 #> 4 FB 2016-12-30 117 117 115 115 18600100 115
# Aggregate FB to yearly data, end of period, and include the first # endpoint as_period(FB, "yearly", side = "end", include_endpoints = TRUE)
#> # A time tibble: 5 x 8 #> # Index: date #> symbol date open high low close volume adjusted #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-01-02 27.4 28.2 27.4 28.0 69846400 28.0 #> 2 FB 2013-12-31 54.1 54.9 53.9 54.7 43076200 54.7 #> 3 FB 2014-12-31 79.5 79.8 77.9 78.0 19935400 78.0 #> 4 FB 2015-12-31 106 106 105 105 18298700 105 #> 5 FB 2016-12-30 117 117 115 115 18600100 115
# Aggregate to weekly. Notice that it only uses the earliest day available # in the data set at that periodicity. It will not set the date of the first # row to 2013-01-01 because that date did not exist in the original data set. as_period(FB, "weekly")
#> # A time tibble: 209 x 8 #> # Index: date #> symbol date open high low close volume adjusted #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-01-02 27.4 28.2 27.4 28.0 69846400 28.0 #> 2 FB 2013-01-07 28.7 29.8 28.6 29.4 83781800 29.4 #> 3 FB 2013-01-14 32.1 32.2 30.6 31.0 98892800 31.0 #> 4 FB 2013-01-22 29.8 30.9 29.7 30.7 55243300 30.7 #> 5 FB 2013-01-28 31.9 32.5 31.8 32.5 59682500 32.5 #> 6 FB 2013-02-04 29.1 29.2 28.0 28.1 92362200 28.1 #> 7 FB 2013-02-11 28.6 28.7 28.0 28.3 37361800 28.3 #> 8 FB 2013-02-19 28.2 29.1 28.1 28.9 49396400 28.9 #> 9 FB 2013-02-25 27.2 27.6 27.2 27.3 34652000 27.3 #> 10 FB 2013-03-04 27.8 28.1 27.4 27.7 32400700 27.7 #> # ... with 199 more rows
# Aggregate to every other week as_period(FB, "2 weeks")
#> Warning: Multi-unit not supported for weeks. Ignoring.
#> Warning: Multi-unit not supported for weeks. Ignoring.
#> # A time tibble: 105 x 8 #> # Index: date #> symbol date open high low close volume adjusted #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-01-02 27.4 28.2 27.4 28.0 69846400 28.0 #> 2 FB 2013-01-14 32.1 32.2 30.6 31.0 98892800 31.0 #> 3 FB 2013-01-28 31.9 32.5 31.8 32.5 59682500 32.5 #> 4 FB 2013-02-11 28.6 28.7 28.0 28.3 37361800 28.3 #> 5 FB 2013-02-25 27.2 27.6 27.2 27.3 34652000 27.3 #> 6 FB 2013-03-11 28.0 28.6 27.8 28.1 35642100 28.1 #> 7 FB 2013-03-25 25.8 25.8 25.1 25.1 39199000 25.1 #> 8 FB 2013-04-08 27.2 27.2 26.6 26.8 27256000 26.8 #> 9 FB 2013-04-22 25.8 26.4 25.7 26.0 25687600 26.0 #> 10 FB 2013-05-06 28.3 28.5 27.5 27.6 43939400 27.6 #> # ... with 95 more rows
# FB is daily data, aggregate to minute? # Not allowed for Date class indices, an error is thrown # as_period(FB, "minute") # Grouped usage ------------------------------------------------------------- # FANG contains Facebook, Amazon, Netflix and Google stock prices data(FANG) FANG <- as_tbl_time(FANG, date) FANG <- dplyr::group_by(FANG, symbol) # Respects groups as_period(FANG, "yearly")
#> # A time tibble: 16 x 8 #> # Index: date #> # Groups: symbol [4] #> symbol date open high low close volume adjusted #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-01-02 27.4 28.2 27.4 28.0 69846400 28.0 #> 2 FB 2014-01-02 54.8 55.2 54.2 54.7 43195500 54.7 #> 3 FB 2015-01-02 78.6 78.9 77.7 78.4 18177500 78.4 #> 4 FB 2016-01-04 102 102 99.8 102 37912400 102 #> 5 AMZN 2013-01-02 256 258 253 257 3271000 257 #> 6 AMZN 2014-01-02 399 399 394 398 2137800 398 #> 7 AMZN 2015-01-02 313 315 307 309 2783200 309 #> 8 AMZN 2016-01-04 656 658 628 637 9314500 637 #> 9 NFLX 2013-01-02 95.2 95.8 90.7 92.0 19431300 13.1 #> 10 NFLX 2014-01-02 367 368 361 363 12325600 51.8 #> 11 NFLX 2015-01-02 344 352 341 349 13475000 49.8 #> 12 NFLX 2016-01-04 109 110 105 110 20794800 110 #> 13 GOOG 2013-01-02 719 727 717 723 5101500 361 #> 14 GOOG 2014-01-02 1115 1118 1108 1113 3656400 556 #> 15 GOOG 2015-01-02 529 531 524 525 1447500 525 #> 16 GOOG 2016-01-04 743 744 731 742 3272800 742
# Every 6 months, respecting groups as_period(FANG, "6 months")
#> # A time tibble: 32 x 8 #> # Index: date #> # Groups: symbol [4] #> symbol date open high low close volume adjusted #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-01-02 27.4 28.2 27.4 28.0 69846400 28.0 #> 2 FB 2013-07-01 25.0 25.1 24.6 24.8 20582200 24.8 #> 3 FB 2014-01-02 54.8 55.2 54.2 54.7 43195500 54.7 #> 4 FB 2014-07-01 67.6 68.4 67.4 68.1 33243000 68.1 #> 5 FB 2015-01-02 78.6 78.9 77.7 78.4 18177500 78.4 #> 6 FB 2015-07-01 86.8 87.9 86.5 86.9 25260000 86.9 #> 7 FB 2016-01-04 102 102 99.8 102 37912400 102 #> 8 FB 2016-07-01 114 115 114 114 14980000 114 #> 9 AMZN 2013-01-02 256 258 253 257 3271000 257 #> 10 AMZN 2013-07-01 279 283 277 282 2888200 282 #> # ... with 22 more rows
# Using start_date ---------------------------------------------------------- #### One method using start_date # FB stock prices data(FB) FB <- as_tbl_time(FB, date) # The Facebook series starts at 2013-01-02 so the 'every 2 day' counter # starts at that date as well. Groups become (2013-01-02, 2013-01-03), # (2013-01-04, 2013-01-05) and so on. as_period(FB, "2 day")
#> # A time tibble: 619 x 8 #> # Index: date #> symbol date open high low close volume adjusted #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-01-02 27.4 28.2 27.4 28.0 69846400 28.0 #> 2 FB 2013-01-03 27.9 28.5 27.6 27.8 63140600 27.8 #> 3 FB 2013-01-07 28.7 29.8 28.6 29.4 83781800 29.4 #> 4 FB 2013-01-09 29.7 30.6 29.5 30.6 104787700 30.6 #> 5 FB 2013-01-11 31.3 32.0 31.1 31.7 89598000 31.7 #> 6 FB 2013-01-14 32.1 32.2 30.6 31.0 98892800 31.0 #> 7 FB 2013-01-15 30.6 31.7 29.9 30.1 173242600 30.1 #> 8 FB 2013-01-17 30.1 30.4 30.0 30.1 40256700 30.1 #> 9 FB 2013-01-22 29.8 30.9 29.7 30.7 55243300 30.7 #> 10 FB 2013-01-23 31.1 31.5 30.8 30.8 48899800 30.8 #> # ... with 609 more rows
# Specifying the `start_date = "2013-01-01"` might be preferable. # Groups become (2013-01-01, 2013-01-02), (2013-01-03, 2013-01-04) and so on. as_period(FB, "2 day", start_date = "2013-01-01")
#> # A time tibble: 619 x 8 #> # Index: date #> symbol date open high low close volume adjusted #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-01-02 27.4 28.2 27.4 28.0 69846400 28.0 #> 2 FB 2013-01-03 27.9 28.5 27.6 27.8 63140600 27.8 #> 3 FB 2013-01-07 28.7 29.8 28.6 29.4 83781800 29.4 #> 4 FB 2013-01-09 29.7 30.6 29.5 30.6 104787700 30.6 #> 5 FB 2013-01-11 31.3 32.0 31.1 31.7 89598000 31.7 #> 6 FB 2013-01-14 32.1 32.2 30.6 31.0 98892800 31.0 #> 7 FB 2013-01-15 30.6 31.7 29.9 30.1 173242600 30.1 #> 8 FB 2013-01-17 30.1 30.4 30.0 30.1 40256700 30.1 #> 9 FB 2013-01-22 29.8 30.9 29.7 30.7 55243300 30.7 #> 10 FB 2013-01-23 31.1 31.5 30.8 30.8 48899800 30.8 #> # ... with 609 more rows
#### Equivalent method using an index vector # FB stock prices data(FB) FB <- as_tbl_time(FB, date) custom_period <- create_series( time_formula = dplyr::first(FB$date) - 1 ~ dplyr::last(FB$date), period = "2 day", class = "Date", as_vector = TRUE) FB %>% as_tbl_time(date) %>% as_period(period = custom_period)
#> # A time tibble: 619 x 8 #> # Index: date #> symbol date open high low close volume adjusted #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-01-02 27.4 28.2 27.4 28.0 69846400 28.0 #> 2 FB 2013-01-03 27.9 28.5 27.6 27.8 63140600 27.8 #> 3 FB 2013-01-07 28.7 29.8 28.6 29.4 83781800 29.4 #> 4 FB 2013-01-09 29.7 30.6 29.5 30.6 104787700 30.6 #> 5 FB 2013-01-11 31.3 32.0 31.1 31.7 89598000 31.7 #> 6 FB 2013-01-14 32.1 32.2 30.6 31.0 98892800 31.0 #> 7 FB 2013-01-15 30.6 31.7 29.9 30.1 173242600 30.1 #> 8 FB 2013-01-17 30.1 30.4 30.0 30.1 40256700 30.1 #> 9 FB 2013-01-22 29.8 30.9 29.7 30.7 55243300 30.7 #> 10 FB 2013-01-23 31.1 31.5 30.8 30.8 48899800 30.8 #> # ... with 609 more rows
# Manually calculating returns at different periods ------------------------- data(FB) # Annual Returns # Convert to end of year periodicity, but include the endpoints to use as # a reference for the first return calculation. Then calculate returns. FB %>% as_tbl_time(date) %>% as_period("1 y", side = "end", include_endpoints = TRUE) %>% dplyr::mutate(yearly_return = adjusted / dplyr::lag(adjusted) - 1)
#> # A time tibble: 5 x 9 #> # Index: date #> symbol date open high low close volume adjusted yearly_return #> <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 FB 2013-01-02 27.4 28.2 27.4 28.0 69846400 28.0 NA #> 2 FB 2013-12-31 54.1 54.9 53.9 54.7 43076200 54.7 0.952 #> 3 FB 2014-12-31 79.5 79.8 77.9 78.0 19935400 78.0 0.428 #> 4 FB 2015-12-31 106 106 105 105 18298700 105 0.341 #> 5 FB 2016-12-30 117 117 115 115 18600100 115 0.0993