【问题标题】:How can I decorate a function in R?如何在 R 中装饰函数?
【发布时间】:2016-06-15 08:16:56
【问题描述】:

我正在尝试使用 R 中的一些功能,用我自己的版本替换它们,这些版本记录一些信息,然后调用原始版本。我的问题是,我如何构造调用以使其完全复制原始参数。

首先,我们将设置一个环境

   env <- new.env()

我可以做到这一点的一种方法是接听电话并对其进行修改。但是,我不知道如何使用原始函数来做到这一点。

## Option 1: get the call and modify it
env$`[` <- function(x, i, j, ...) {
    my.call <- match.call()
    ## This isn't allowed.
    my.call[[1]] <- as.name(.Primitive("["))

    record.some.things.about(i, j)

    eval(my.call, envir = parent.frame())
}

或者,我可以只获取参数并使用do.call。但是,我还没有弄清楚如何正确提取参数。

## Option 2: do a call with the arguments
env$`[` <- function(x, i, j, ...) {
    ## This outputs a list, so if 'i' is missing, then 'j' ends up in the 'i' position.
    ## If I could get an alist here instead, I could keep 'j' in the right position.
    my.args <- match.call()[-1]

    record.some.things.about(i, j)

    do.call(
        .Primitive("["),
        my.args,
        envir = parent.frame()
    )
}

然后,如果我们做对了,我们可以在我们构建的环境中评估一些使用[ 的表达式,然后调用我们的检测函数:

## Should return data.frame(b = c(4, 5, 6))
evalq(
    data.frame(a = c(1, 2, 3), b = c(4, 5, 6))[, "b"],
    envir = env
)

任何人都可以提供帮助/建议吗?

【问题讨论】:

  • 我倾向于修复一些默认值的方法如下:假设我希望table 始终包含缺失值,然后在我的脚本开头使用table &lt;- function(x, ...) base:::table(x, ..., useNA="ifany")。无论您想记录关于ij 的任何内容,您都可以按照类似的思路构建一些东西。
  • 你能更清楚地解释你想要达到的目标吗?如果我理解正确,您要么想为[ 编写一个方法,要么想用您自己的函数替换[。但是,您的函数名称让我感到困惑。
  • 现在你把这件事弄得更糊涂了。您将功能分配给环境。为什么?
  • 我真的建议你走一条不同的路。创建一个 S3 类并为[ 定义一个方法。

标签: r metaprogramming decorator


【解决方案1】:

使用trace:

trace(`[.data.frame`, quote({print("hello!")}), at = 1) 
iris[1,]
#Tracing `[.data.frame`(iris, 1, ) step 1 
#[1] "hello!"
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1          5.1         3.5          1.4         0.2  setosa

【讨论】:

    【解决方案2】:

    你不能用三点 arg 捕获原始函数 args 的所有内容,然后传递给原始函数吗?

    sum <- function(..., na.rm = TRUE) {
      print("my sum") # here is where you can "record some info"
      base::sum(..., na.rm = na.rm) # then call original function w/ ...
    }
    
    base::sum(5,5, NA)
    ##[1] NA
    
    # your function
    sum(5,5, NA)
    ##[1] "my sum"
    ##[1] 10
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-07
      • 2019-07-29
      • 2023-02-08
      • 2015-06-26
      • 2015-05-27
      • 2013-01-20
      • 1970-01-01
      • 2010-12-30
      相关资源
      最近更新 更多