我如何装饰R中的函数?
How can I decorate a function in R?
我正在尝试检测 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
)
任何人都可以 help/advise?
你不能用三点 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
使用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
我正在尝试检测 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
)
任何人都可以 help/advise?
你不能用三点 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
使用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