简体   繁体   English

如何在R中的函数内使用dplyr / magrittr的管道?

[英]How can I use dplyr/magrittr's pipe inside functions in R?

I'm trying to write a function which takes as argument a dataframe and the name of the function. 我正在尝试编写一个函数,它将数据帧和函数的名称作为参数。 When I try to write the function with the standard R syntax, I can get the good result using eval and substitute as recommanded by @hadley in http://adv-r.had.co.nz/Computing-on-the-language.html 当我尝试使用标准R语法编写函数时,我可以使用eval获得良好的结果,并在http://adv-r.had.co.nz/Computing-on-the-language中按@hadley的推荐substitute html的

> df <- data.frame(y = 1:10)
> f <- function(data, x) {
+   out <- mean(eval(expr = substitute(x), envir = data))
+   return(out)
+ }
> f(data = df, x = y)
[1] 5.5

Now, when I try to write the same function using the %>% operator, it doesn't work : 现在,当我尝试使用%>%运算符编写相同的函数时,它不起作用:

> df <- data.frame(y = 1:10)
> f <- function(data, x) {
+   data %>% 
+     eval(expr = substitute(x), envir = .) %>% 
+     mean()
+ }
> f(data = df, x = y)
Show Traceback
Rerun with Debug
 Error in eval(expr, envir, enclos) : objet 'y' introuvable 
> 

How can I using the combine the piping operator with the use of eval and substitute ? 如何使用管道操作器与evalsubstitute的组合使用? It's seems really tricky for me. 这对我来说似乎很棘手。

A workaround would be 解决方法是

f <- function(data, x) {
  v <- substitute(x)
  data %>% 
    eval(expr = v, envir = .) %>%
    mean()
}

The problem is that the pipe functions ( %>% ) are creating another level of closure which interferes with the evaluation of substitute(x) . 问题是管道函数( %>% )正在创建另一个级别的闭包,这会干扰substitute(x)的评估。 You can see the difference with this example 你可以看到这个例子的不同之处

df <- data.frame(y = 1:10)
f1 <- function(data, x) {
  print(environment())
  eval(expr = environment(), envir = data)
}

f2 <- function(data, x) {
  print(environment())
  data %>% 
    eval(expr = environment(), envir = .)
}
f1(data = df, x = y)
# <environment: 0x0000000006388638>
# <environment: 0x0000000006388638>
f2(data = df, x = y)
# <environment: 0x000000000638a4a8>
# <environment: 0x0000000005f91ae0>

Notice how the environments differ in the matrittr version. 请注意matrittr版本中的环境有何不同。 You want to take care of substitute stuff as soon as possible when mucking about with non-standard evaluation. 在非标准评估时,你想尽快照顾substitute品。

I hope your use case is a bit more complex than your example, because it seems like 我希望你的用例比你的例子更复杂,因为它看起来像

mean(df$y)

would be a much easier bit of code to read. 将是一个更容易阅读的代码。

I've been trying to understand my problem. 我一直在努力理解我的问题。

First, I've written what I want with the summarise() function : 首先,我用summarise()函数编写了我想要的东西:

> library(dplyr)
> df <- data.frame(y = 1:10)
> summarise_(.data = df, mean = ~mean(y))
  mean
1  5.5

Then I try to program my own function. 然后我尝试编写自己的函数。 I've found a solution which seems to work with the lazyeval package in this post . 我发现这似乎与合作解决lazyeval包在这篇文章 I use the lazy() and the interp() functions to write what I want. 我使用lazy()interp()函数来编写我想要的东西。

The first possibility is here : 第一种可能性在这里:

> library(lazyeval)
> f <- function(data, col) {
+   col <- lazy(col)
+   inter <- interp(~mean(x), x = col)
+   summarise_(.data = data, mean = inter)    
+   }
> f(data = df, col = y)
  mean
1  5.5

I can also use pipes : 我也可以使用管道:

> f <- function(data, col) {
+   col <- lazy(col)
+   inter <- interp(~mean(x), x = col)
+   data %>% 
+     summarise_(.data = ., mean = inter)    
+ }
> 
> f(data = df, col = y)
  mean
1  5.5

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用dplyr和magrittr将数据操作传递给需要数字向量的函数? - How can I use dplyr and magrittr to pipe a data manipulation into a function that requires a numeric vector? 如何在dplyr / magrittr管道中使用base :: rowSums()(%&gt;%) - How to use base::rowSums() with dplyr/magrittr pipe (%>%) R函数中的Magrittr管道 - Magrittr pipe in R functions 为什么在调用R的split函数时不能使用显式形式而不是magrittr管道? - Why can't I use the explicit form instead of a magrittr pipe in a call to R's split function? 嵌套 base-R 函数时,如何使 magrittr 的 pipe 运算符 (%>%) 起作用? - How to make magrittr's pipe operator (%>%) work when nesting base-R functions? R:我可以在 magrittr 中更新 object 的 class 吗? - R: can I update the class of a an object in a magrittr pipe? 如何在R中使用带有附加参数的magrittr管道运算符 - How to use the magrittr pipe operator in R with additional arguments 我如何“magrittr”管道到 R 包“Hmisc”的 summarise() 函数? - How do I 'magrittr' pipe to the summarize() function of the R package 'Hmisc'? 我如何在 vscode 中从 R 获得 magrittr pipe 的别名 - How do I had an alias for magrittr pipe from R in vscode 我可以使用 dplyr 管道而不是覆盖 R 中的列表吗? - Can I use a dplyr pipe instead of lapplying over lists in R?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM