rollify: Create a rolling version of any function

Description Usage Arguments Details See Also Examples

View source: R/rollify.R

Description

'rollify' returns a rolling version of the input function, with a rolling 'window' specified by the user.

Usage

1
rollify(.f, window = 1, unlist = TRUE, na_value = NULL)

Arguments

.f

A function, formula, or atomic vector.

If a function, it is used as is.

If a formula, e.g. ~ .x + 2, it is converted to a function. There are three ways to refer to the arguments:

  • For a single argument function, use .

  • For a two argument function, use .x and .y

  • For more arguments, use ..1, ..2, ..3 etc

This syntax allows you to create very compact anonymous functions.

If character vector, numeric vector, or list, it is converted to an extractor function. Character vectors index by name and numeric vectors index by position; use a list to index by position and name at different levels. Within a list, wrap strings in get-attr() to extract named attributes. If a component is not present, the value of .default will be returned.

window

The window size to roll over

unlist

If the function returns a single value each time it is called, use 'unlist = TRUE'. If the function returns more than one value, or a more complicated object (like a linear model), use 'unlist = FALSE' to create a list-column of the rolling results.

na_value

A default value for the 'NA' values at the beginning of the roll.

Details

The intended use of 'rollify' is to turn a function into a rolling version of itself for use inside of a call to [dplyr::mutate()], however it works equally as well when called from [purrr::map()].

Because of it's intended use with [dplyr::mutate()], 'rollify' always returns output with the same length of the input, aligned right, and filled with 'NA' unless otherwise specified by 'na_value'.

The form of the '.f' argument is the same as the form that can be passed to [purrr::map()]. Use '.x' or '.' to refer to the first object to roll over, and '.y' to refer to the second object if required. The examples explain this further.

If optional arguments to the function are required, specify them in the call to 'rollify', and not in the call to the rolling version of the function. See the examples for more details.

See Also

[purrr::safely], [purrr::possibly]

Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# Rolling mean --------------------------------------------------------------

data(FB)

# Turn the normal mean function into a rolling mean with a 5 row window
mean_roll_5 <- rollify(mean, window = 5)

dplyr::mutate(FB,
       normal_mean  = mean(adjusted),
       rolling_mean = mean_roll_5(adjusted))

# There's nothing stopping you from combining multiple rolling functions with
# different window sizes in the same mutate call
mean_roll_10 <- rollify(mean, window = 10)

dplyr::mutate(FB,
       rolling_mean_5  = mean_roll_5(adjusted),
       rolling_mean_10 = mean_roll_10(adjusted))

# Functions with multiple args and optional args ----------------------------

# With 2 args, use the purrr syntax of ~ and .x, .y
# Rolling correlation example
cor_roll <- rollify(~cor(.x, .y), window = 5)

dplyr::mutate(FB, running_cor = cor_roll(adjusted, open))

# With >2 args, create an anonymous function with >2 args or use
# the purrr convention of ..1, ..2, ..3 to refer to the arguments
avg_of_avgs <- rollify(function(x, y, z) {
                         (mean(x) + mean(y) + mean(z)) / 3
                       },
                       window = 10)

# Or
avg_of_avgs <- rollify(~(mean(..1) + mean(..2) + mean(..3)) / 3,
                       window = 10)

dplyr::mutate(FB, avg_of_avgs = avg_of_avgs(open, high, low))

# Optional arguments MUST be passed at the creation of the rolling function
# Only data arguments that are "rolled over" are allowed when calling the
# rolling version of the function
FB$adjusted[1] <- NA

roll_mean_na_rm <- rollify(~mean(.x, na.rm = TRUE), window = 5)

dplyr::mutate(FB, roll_mean = roll_mean_na_rm(adjusted))

# Returning multiple values -------------------------------------------------

data(FB)

# If the function returns >1 value, set the `unlist = FALSE` argument
# Running 5 number summary
summary_roll <- rollify(summary, window = 5, unlist = FALSE)

FB_summarised <- dplyr::mutate(FB, summary_roll = summary_roll(adjusted))
FB_summarised$summary_roll[[5]]

# Rolling regressions -------------------------------------------------------

# Extending an example from R 4 Data Science on "Many Models".
# For each country in the gapminder data, calculate a linear regression
# every 5 periods of lifeExp ~ year
library(gapminder)

# Rolling regressions are easy to implement
lm_roll <- rollify(~lm(.x ~ .y), window = 5, unlist = FALSE)

gapminder %>%
  dplyr::group_by(country) %>%
  dplyr::mutate(rolling_lm = lm_roll(lifeExp, year))

# Rolling with groups -------------------------------------------------------

# One of the most powerful things about this is that it works with
# groups since `mutate` is being used
data(FANG)
FANG <- FANG %>%
  dplyr::group_by(symbol)

mean_roll_3 <- rollify(mean, window = 3)

FANG %>%
  dplyr::mutate(mean_roll = mean_roll_3(adjusted)) %>%
  dplyr::slice(1:5)

DavisVaughan/tibbletime3 documentation built on May 28, 2019, 12:25 p.m.