为什么命令在 R 的管道运算符中不起作用,但在管道之外却运行得很好?

Chr*_*s12 2 r

我的数据框包含选项数据。我想为每个交易日找到最接近货币的选项。很遗憾

ir_OEX_data %>% group_by(quotedate) %>% which.min(abs(moneyness_call  - 1))
Run Code Online (Sandbox Code Playgroud)

导致以下错误:

which.min(., abs(ir_OEX_data$moneyness_call - 1)) 中的错误:未使用参数 (abs(ir_OEX_data$moneyness_call - 1))

但当我单独跑步时:

 which.min(abs(ir_OEX_data$moneyness_call  - 1))
Run Code Online (Sandbox Code Playgroud)

该命令运行得非常好。

我在这里犯了什么错误?

zep*_*ryl 6

问题:并非所有函数都适合管道

{magrittr} 管道与编写为“管道友好”的函数配合使用效果最佳。这些通常将数据帧作为第一个参数,并且可以使用数据屏蔽来让您引用该数据帧中的列,而无需为其添加前缀。例如,许多 {dplyr} 动词是管道友好的。

which.min不适合管道。你的代码,

ir_OEX_data %>% group_by(quotedate) %>% which.min(abs(moneyness_call  - 1))
Run Code Online (Sandbox Code Playgroud)

实际上相当于

which.min(
  group_by(ir_OEX_data, quotedate), 
  abs(moneyness_call  - 1)
)
Run Code Online (Sandbox Code Playgroud)

which.min只需要一个参数,因此会引发错误。

解决方案1:exexpo管道(%$%)

有几种方法可以解决这个问题。一个是 {magrittr} 说明管道,%$%它使您的列名称可用于下一个函数,而无需传递数据:

library(magrittr)
library(dplyr)

ir_OEX_data %>% 
  group_by(quotedate) %$% 
  which.min(abs(moneyness_call  - 1))
Run Code Online (Sandbox Code Playgroud)

解决方案 2:在管道友好函数内使用

如果您想将 的结果添加which.min到数据集中,您只需在summarizeor内部使用它mutate

ir_OEX_data %>% 
  group_by(quotedate) %>% 
  summarize(call_which_min = which.min(abs(moneyness_call  - 1)))
Run Code Online (Sandbox Code Playgroud)

解决方案 3:编写一个管道友好的包装器

您还可以将不友好的函数放入管道友好的包装器中。这在这里可能有点矫枉过正,但在更复杂的情况下可能很有用。

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))
Run Code Online (Sandbox Code Playgroud)