使用R中的quo()评估作为另一个函数中的争论的函数

时间:2017-09-13 10:13:52

标签: r dplyr rlang

我创建了一个函数,它将另一个函数作为参数,参数函数将原始函数提供的某个对象(在示例中为向量)作为其参数。以正确的方式进行函数调用一直是一项挑战。以下是我阅读Programming with dplyr后使用的三种方法。 只有选项三有效,

我想知道这是否是评估函数内函数的最佳方法。

library(dplyr);library(rlang)
#Function that will be passed as an arguement
EvaluateThis1 <- quo(mean(vector))
EvaluateThis2 <- ~mean(vector)
EvaluateThis3 <- quo(mean)

#First function that will recieve a function as an argument
MyFunc <- function(vector, TheFunction){

  print(TheFunction)
  eval_tidy(TheFunction)
}

#Second function that will recieve a function as an argument
MyFunc2 <- function(vector, TheFunction){

  print(TheFunction)
  quo(UQ(TheFunction)(vector)) %>%
    eval_tidy
}

#Option 1

#This is evaluating vector in the global environment where 
#EvaluateThis1 was captured
MyFunc(1:4, EvaluateThis1)

#Option 2

#I don't know what is going on here
MyFunc(1:4, EvaluateThis2)
MyFunc2(1:4, EvaluateThis2)
#Option 3

#I think this Unquotes the function splices in the arguement then
#requotes before evaluating.
MyFunc2(1:4, EvaluateThis3)

我的问题是:

  1. 选项3是执行此评估的最佳/最简单的方法
  2. 对正在发生的事情的解释
  3. 修改

    阅读@Rui Barradas非常清晰简洁的回答后,我意识到我实际上正在尝试做类似下面的事情,我没有设法使用Rui的方法工作但是使用环境设置解决了< / p>

    OtherStuff <-c(10, NA)
    
    EvaluateThis4 <-quo(mean(c(vector,OtherStuff), na.rm = TRUE))
    
    
    MyFunc3 <- function(vector, TheFunction){
      #uses the captire environment which doesn't contain the object vector
      print(get_env(TheFunction))
    
      #Reset the enivronment of TheFunction to the current environment where vector exists
      TheFunction<- set_env(TheFunction, get_env())
    
      print(get_env(TheFunction))
    
      print(TheFunction)
      TheFunction %>%
        eval_tidy
    }
    
    
    MyFunc3(1:4, EvaluateThis4)
    

    在当前环境而非捕获环境中评估函数。因为没有对象&#34; OtherStuff&#34;在该环境中,搜索父环境以查找&#34; OtherStuff&#34;在全球环境中。

1 个答案:

答案 0 :(得分:3)

我将尝试回答问题1 我认为,执行此类评估的最佳和最简单的方法是不使用任何花哨的评估技术。直接调用该函数通常有效。使用您的示例,请尝试以下操作。

EvaluateThis4 <- mean  # simple

MyFunc4 <- function(vector, TheFunction){
  print(TheFunction)
  TheFunction(vector)  # just call it with the appropriate argument(s)
}

MyFunc4(1:4, EvaluateThis4)
function (x, ...) 
UseMethod("mean")
<bytecode: 0x000000000489efb0>
<environment: namespace:base>
[1] 2.5

在基础R中有这样的示例。例如,approxfunecdf都返回可以直接在代码中使用的函数来执行后续计算。这就是为什么我这样定义EvaluateThis4 至于使用函数作为参数的函数,有优化函数,当然还有*applybyave

关于问题2,我必须承认我完全无知。