r - 使用 'bquote'(或替代方法)从符号构造函数

标签 r function metaprogramming

假设我有一个“symbol”类型的对象,表示一个函数的名称。例如:

nm <- quote(mean)

我想构造一个函数f,其主体使用由符号nm 命名的函数。例如:

f <- function(x, do = c("something", "nothing")) {
  switch(match.arg(do), something = mean(x), nothing = x)
}

我想以相同的方式构造此函数,这意味着我对以下方法感到满意:

factory <- function(name) {
  func <- match.fun(name)
  function(x, do = c("something", "nothing")) {
    switch(match.arg(do), something = func(x), nothing = x)
  }
}
g <- factory(nm)

因为 g 的主体不是 body(f)g 的环境不是 environment(f).

我考虑过的一种方法是 bquote:

h <- eval(bquote({
  function(x, do = c("something", "nothing")) {
    switch(match.arg(do), something = .(nm)(x), nothing = x)
  }
}))

bquote 让我了解了大部分内容,但一个问题是 hprint 输出不包含替换值nm 默认:

h
## function(x, do = c("something", "nothing")) {
##     switch(match.arg(do), something = .(nm)(x), nothing = x)
##   }

print(h, useSource = FALSE)
## function (x, do = c("something", "nothing")) 
## {
##     switch(match.arg(do), something = mean(x), nothing = x)
## }

原因似乎是hsrcref属性:

identical(f, h)
## [1] TRUE
identical(f, h, ignore.srcref = FALSE)
## [1] FALSE

我的问题是:如何解决从 nm 构造 f 的一般问题?

我对构造函数 h 的条件是 identical(f, h) 应该是 TRUE 并且 的输出print(h) 应包含 nm 的替换值,类似于 print(f)

我欢迎改进我现有的 bquote 方法的答案,或者建议新方法的答案,或者解释为什么我想做的事情实际上不可能的答案......

最佳答案

不是特别优雅,但是 parse(deparse( 似乎可行:

nm <- quote(mean)
f <- function(x, do = c("something", "nothing")) {
  switch(match.arg(do), something = mean(x), nothing = x)
}

eval(parse(text=deparse(bquote(h <- function(x, do = c("something", "nothing")) {
  switch(match.arg(do), something = .(nm)(x), nothing = x)
}))))

identical(f, h)
#> [1] TRUE
print(f)
#> function(x, do = c("something", "nothing")) {
#>   switch(match.arg(do), something = mean(x), nothing = x)
#> }
print(h)
#> function(x, do = c("something", "nothing")) {
#>     switch(match.arg(do), something = mean(x), nothing = x)
#> }

srcref 与预期的不同:

identical(f, h, ignore.srcref = FALSE)
#> [1] FALSE
attributes(attributes(f)$srcref)$srcfile$lines
#> [1] "f <- function(x, do = c(\"something\", \"nothing\")) {"     
#> [2] "  switch(match.arg(do), something = mean(x), nothing = x)"
#> [3] "}"
attributes(attributes(h)$srcref)$srcfile$lines
#> [1] "h <- function(x, do = c(\"something\", \"nothing\")) {"     
#> [2] "    switch(match.arg(do), something = mean(x), nothing = x)"
#> [3] "}"

关于r - 使用 'bquote'(或替代方法)从符号构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70287497/

相关文章:

r - 如何在 Shiny 中保存传单 map

excel - 如何使用 vba 检索内置 excel 函数的完整列表?

reflection - 遍历 Scheme 函数作为列表

c++ - 了解类模板特化示例的隐式实例化

c++ - 将成员模板 typedef 与 using 别名会使编译器认为它不是类模板

r - 通过 R 中的变量填充数据框日期

r - 获取 R 中向量每 10 步的平均值

python - 类型错误 : use() got an unexpected keyword argument 'warn' when importing matplotlib

r - `weighted.mean` 在带有可选参数的函数中?

c - C函数中的多维char数组