R:如何编写一个用另一个函数调用替换函数调用的函数?

R: How to write a function that replaces a function call with another function call?

例如我要改造代码

mean(x)

fn(x)

每次我在代码中看到 mean

replace_mean <- function(code) {
  substitute(code, list(mean = fn)) # doesn't work
  substitute(substitute(code), list(mean = fn)) # doesn't work
}

以上两种方法都不行。例如

replace_mean(list(mean(y), mean(x)))

在 R 中使用 NSE 进行函数替换的最佳方法是什么?

首选 Base R 解决方案。

更新示例输出

replace(mean(x)) # fn(x)

replace(list(a = mean(x), mean(ok))) # list(a=fn(x), fn(ok)))

下面的函数,当传递mean(x)和一些fn比如sqrt作为它的两个参数returns调用对象fn(x),即sqrt(x),将出现的 mean 替换为 fn

replace_mean <- function(code, fn) {
  do.call("substitute", list(substitute(code), list(mean = substitute(fn))))
}

例子

1) 基本示例

e <- replace_mean(mean(x), sqrt)
e
## sqrt(x)

x <- 4
eval(e)
## [1] 2

2) 更复杂的表达式

ee <- replace_mean(mean(x) + mean(x*x), sqrt)
ee
## sqrt(x) + sqrt(x * x)

x <- 4
eval(ee)
## [1] 6

3) 将 replace_mean 应用于 f 的主体,创建 g

f <- function(x) mean(x) + mean(x*x)
g <- f
body(g) <- do.call("replace_mean", list(body(f), quote(sqrt)))

g
## function (x) 
## sqrt(x) + sqrt(x * x)

x <- 4
g(x)
## [1] 6

一种方法更丑陋,它依赖于字符串操作来生成您想要的代码运行,然后对其进行评估。

replace_mean <- function(code) {
  code_subbed = substitute(code)

  # constructu the code I want
  code_subbed_subbed = sprintf("substitute(%s, list(mean=quote(fn)))", deparse(code_subbed))

  eval(parse(text = code_subbed_subbed))
}

replace_mean(list(mean(x), a=  mean(ok)))