0

我制作了一个函数,该函数将另一个函数作为参数,该参数函数将原始函数提供的某个对象(在示例中为向量)作为其参数。以正确的方式进行函数调用一直具有挑战性。以下是我在阅读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. 正在发生的事情的解释

编辑

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

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)

该函数在当前环境而不是捕获环境中进行评估。因为在该环境中没有对象“OtherStuff”,所以在全局环境中搜索父环境以找到“OtherStuff”。

4

1 回答 1

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
至于使用函数作为参数的函数,有优化函数,当然还有*apply,byave

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

于 2017-09-13T10:48:23.057 回答