My dataframe includes options data. I want to find the closest to the money option for every trading date. Unfortunately
ir_OEX_data %>% group_by(quotedate) %>% which.min(abs(moneyness_call - 1))
leads to the following error:
Error in which.min(., abs(ir_OEX_data$moneyness_call - 1)) : unused argument (abs(ir_OEX_data$moneyness_call - 1))
But when I run solely:
which.min(abs(ir_OEX_data$moneyness_call - 1))
The command works perfectly fine.
What is my mistake here?
{magrittr} pipes work best with functions written to be "pipe-friendly." These generally take a dataframe as a first argument, and may use data masking to let you refer to columns within that dataframe without prefixing them. e.g., many {dplyr} verbs are pipe-friendly.
which.min
isn't pipe-friendly. Your code,
ir_OEX_data %>% group_by(quotedate) %>% which.min(abs(moneyness_call - 1))
is actually equivalent to
which.min(
group_by(ir_OEX_data, quotedate),
abs(moneyness_call - 1)
)
but which.min
expects only one argument, so throws an error.
There are a few ways to deal with this. One is the {magrittr} exposition pipe, %$%
, which makes your column names available to the next function without passing the data:
library(magrittr)
library(dplyr)
ir_OEX_data %>%
group_by(quotedate) %$%
which.min(abs(moneyness_call - 1))
If you wanted to add the result of which.min
to your dataset, you'd just need to use it inside summarize
or mutate
:
ir_OEX_data %>%
group_by(quotedate) %>%
summarize(call_which_min = which.min(abs(moneyness_call - 1)))
You can also put a non-friendly function in a pipe-friendly wrapper. This would probably be overkill here, but can be useful in more complex cases.
which_min_pipe <- function(.data, x) {
.data %>% summarize(out = which.min({{ x }})) %>% pull(out)
}
ir_OEX_data %>%
group_by(quotedate) %>%
which_min_pipe(abs(moneyness_call - 1))